前言
在了解什么是Python类之前,先来了解一下什么是面向对象编程:
一、什么是面向对象编程
1、面向对象编程(oop)是一种程序设计思想。oop把对象作为程序的基本单元,一个对象包含数据和操作数据的函数
2、在python中,所有数据类型都被视为对象,也可以自定义对象。自定义对象数据类型就是面向对象中类的概念
二、面向对象术语简介
术语 | 意义 |
---|
类(class) | 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例 | 方法 | 类中定义的函数 | 类变量(属性) | 类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体(方法)之外。类变量通常不作为实例变量使用,类变量也称作属性 | 数据成员 | 类变量或者实例变量用于处理类及其实例对象的相关的数据 | 方法重写 | 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写 | 实例变量 | 定义在__init__方法中的变量,只作用于当前实例的类 | 继承 | 即一个派生类(derived class)继承基类(base class)的字段和方法 | 实例化 | 创建一个类的实例,类的具体对象。一个类可以实例化出无数个对象 | 对象 | 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法 | 多态 | 对不同的类使用不同的工作 | 封装 | 对外部世界隐藏对象的工作细节 |
三、Python类
Python的类提供了面向对象编程的所有标准特性: ⑴类继承机制允许多个基类,派生类可以覆盖它基类的任何方法,一个方法可以调用基类中相同名称的的方法 ⑵对象可以包含任意数量和类型的数据 ⑶和模块一样,类也拥有Python天然的动态特性:它们在运行时创建,可以在创建后修改
类的定义
class MyStudent:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
self.__secret = 0
def studentName(self,name):
print(f'student name is{self.name}')
t = MyStudent('小王',11,0)
t.studentName('小李')
1.一般使用 class 语句来创建一个新类,class之后为类的名称(通常首字母大写)并以冒号结尾; 2.类中可以定义所使用的方法,类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self; 3.创建类时,可以定义一个特定的方法,名为__init__(),只要创建这个类的一个实例就会运行这个方法。类似于C++中的构造方法,可以通过__init__()方法传递参数。 4.self 代表类的实例,self 在定义类的方法时是必须有的,用来实例化类定义的函数和变量; 5.__private_attrs 两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。
classmethod类方法
类方法(装饰器),第一个参数是cls,代表这个类(注意不是类实例),常用来调用类级方法(如系统方法跟静态方法,类方法等)来进行预处理,然后返回预处理后的类。效果就像另一个构造函数一样(实际上并不是)
class info(object):
@classmethod
def sayclassmethod(cls):
print 'say %s' % cls
def saymethod(self):
print 'say %s' % self
test = info()
test.saymethod()
test.sayclassmethod()
info.saymethod(test)
info.sayclassmethod()
使用@classmethod是为了处理一些__init__处理不了的赋值问题(一般是参数不对应),可以当成有第二、第三个__init__方法,或者是C++中的构造函数,要通过类名才能显示调用。
staticmethod静态方法 使用@staticmethod目的之一是为了增加可读性,不需要参数self的方法都可以加上@staticmethod增加可读性,因为,这个方法是类级别的,在调用时要使用类名。
继承类定义 1.单继承
class <类名>(父类名) <语句>
class A:
def __init__(self,n,a,s):
self.name = n
self.age = a
self.sex = s
def speak(self):
print("我现在{}岁了 我叫{} 我的性别是{}".format(self.age,self.name,self.sex))
class B(A):
grade = ''
def __init__(self,name,age,sex,grade):
print('我是子类的__init__')
self.grade = grade
A.__init__(self,name,age,sex)
def speak(self):
A.speak(self)
print("我今年{} 我叫{} 我的成绩是{}".format(self.age,self.name,self.grade))
b = B('张三',18,'男',60)
b.speak()
2.类的多重继承 class 类名(父类1,父类2,…,父类n) <语句1>
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法
class A:
def speak(self):
print('我是A类的speak方法')
def a(self):
print('a')
class B:
def speak(self):
print('我是B类的speak方法')
def b(self):
print('b')
class C(A,B):
def speak(self):
super().speak()
四、类的专业方法
首先需要理解的是,两个下划线开头的函数是声明该属性为私有,不能在类的外部被使用或访问 1__init__() 类似于构造函数,可以通过__init__()方法传递参数,但是一个参数必须为self,后续参数为自己定义。
class Study:
def __init__(self,name=None):
self.name = name
def say(self):
print self.name
study = Study("Badboy")
study.say()
2__del__() 类似于析构函数,析构函数往往是用来是否内存,哪怕不写也会默认调用。
class Study:
def __init__(self,name=None):
self.name = name
def __del__(self):
print "Iamaway,baby!"
def say(self):
print self.name
study = Study("zhuzhengjun")
study.say()
五、理解Self的意义
在Python类中规定,函数的第一个参数是实例对象本身,并且约定俗成,把其名字写为self(可以自定义)。其作用相当于C++中的this指针,表示当前类的对象,可以调用当前类中的属性和方法。 简单的说self就是把 class中定义的变量和函数变成实例变量和实例函数,它和this一样作用域是在类内部,只能在成员函数中使用,使得成员间能互相调用,而不需要从外部调用 数据(即变量)和方法(即函数),以实现数据的封装。 如果不使用self把类中定义的变量和函数实例化,那么在类的成员函数中调用未被实例化的变量或函数便会报错。
self代表类的实例,而非类;self 就是 对象/实例 属性集合
class Box():
def __init__(self, boxname, size, color):
self.boxname = boxname
self.size = size
self.color = color
def open(self, myself):
print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))
print('-->用类自己的self,打开那个%s,%s的%s' % (self.color, self.size, self.boxname))
def close(self):
print('-->关闭%s,谢谢' % self.boxname)
b = Box('魔盒', '14m', '红色')
b.close()
b.open(b)
print(b.__dict__)
在 class 类的函数中,为什么 self是必要的,因为 self 是对象的载体,可以理解成一个字典,看下面代码:
class Box():
def myInit(mySelf, boxname, size, color):
print(mySelf.__dict__)
mySelf.boxname = boxname
mySelf.__dict__['aa'] = 'w'
mySelf.size = size
mySelf.color = color
return mySelf
def open(self, myself):
print(self)
print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))
print('-->用类自己的self,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))
def close(self):
print('-->关闭%s,谢谢' % self.boxname)
b = Box().myInit('魔盒', '14m', '红色')
b.close()
b.open(b)
print(b.__dict__)
故可以把 self 理解成存储实例化对象属性的字典(dict), self 存储属性,而没有动作执行.
六、类和函数的注释规范
类的注释规范
class SampleClass(object):
"""Summary of class here.
Longer class information....
Longer class information....
Attributes:
likes_spam: A boolean indicating if we like SPAM or not.
eggs: An integer count of the eggs we have laid.
"""
def __init__(self, likes_spam=False):
"""Inits SampleClass with blah."""
self.likes_spam = likes_spam
self.eggs = 0
def public_method(self):
"""Performs operation blah."""
函数的注释规范
def func(path, field_storage, temporary):
'''基本描述
详细描述
Args:
path (str): The path of the file to wrap
field_storage (FileStorage): The :class:`FileStorage` instance to wrap
temporary (bool): Whether or not to delete the file when the File instance is destructed
Returns:
BufferedFileStorage: A buffered writable file descriptor
'''
pass
Python风格规范
七、测试用例
实现名为 Human 的Class, 需要有以下三个方法 ,1、getHeight 返回身高 ,2、getName 返回姓名 3、setName 修改姓名 需要有以下三个属性,1、身高 2、姓名 3、年龄
class Human:
def __init__(self,height,name,age):
self.height = height
self.name = name
self.age = age
def getHeight(self):
height = self.getHeight
return height
def getName(self):
name = self.name
return name
def setName(self,sName):
self.name = sName
t = Human(167,'小王',20)
personName = t.getName()
print(f"名字是:{personName}")
personHeight = t.getHeight()
print(f'身高是:{personHeight}')
t.setName('小李')
personName=t.getName()
print(f"名字是:{personName}")
1.如果直接返回一个实例变量,是无法打印对应值的,需要定义一个局部变量来作为返回值使用。 2.实例化类的时候不带括号本质上是给类对象起了一个别名,类似C语言中的typedef关键字,而并不会创建一个实例。 3.调用类方法的时候不加括号,调用的是函数(这个对象),不用等函数执行结束;
|