类与对象
类的作用在于封装代码,关键字为 class
。
实例化可以理解为用 class 为模版创建一个对象,实例化时无需 new
关键字。
1 | class Student(): |
注:
1.类名首字母大写,驼峰式命名
2.定义变量、函数
3.类中方法的参数必须有self
,否则会报错。如下
1 | Traceback (most recent call last): |
4.self.name
中的self
不可省略,否则会报错。如下
1 | Traceback (most recent call last): |
5.类只用于定义,不可在类中调用和运行函数
6.函数与方法没有绝对的区别,通常在类中的函数称之为“方法”
7.类与对象通过实例化进行关联,类实例化后即为对象
8.对象中的内容相同,但是对象的内存存储位置不同。通过参数,可将对象不同,如下例。
1 | class Student(): |
类与对象知识主干
1 | python 类 |
构造函数
__init()__
定义了一个构造函数。构造函数的意义在于初始化出不同(内容)的对象实例,不能使用类似方法调用一样传参数。
无参数的构造函数
1 | class Student(): |
- 当实例化时,类会自动调用
__init__()
,无需显式调用。也可以显式调用,但不推荐这样使用。 - 显式调用时,构造函数和普通函数一样,如果没有返回值,则返回
None
。 - 如果对构造函数设置返回值(例如
return 'student'
),只能返回None
,不能返回其他类型,否则会报错。
含参数的构造函数
通常构造函数用于初始化对象的特征,可通过构造函数传入参数,初始化属性值。
1 | class Student(): |
区分模块下的变量与类中的变量
模块中的全局变量和局部变量:
1 | c = 50 |
而类的机制与模块中全局变量和局部变量的机制完全不一样,类中赋值参考下例:
1 | class Student(): |
此处打印出空值的真正原因在于这里的name
和age
是实例变量。一定要注意「类变量」和「实例变量」的差别。
类变量与实例变量
实例变量由类模版创建而来,与对象相关联,与类没有关系。类变量与实例变量的区分方式如下:
- 实例变量的定义方式:
self.xxx
(有self
关键字) - 类变量的定义方式:
xxx
1 | class Student(): |
注:在类里,构造函数中的赋值并不会改变变量的值,但在模块中,函数内的赋值会改变全局变量的值。
实例变量的意义:
考虑将name
和age
设置为类变量是否合理,学生的姓名和年龄应与实例相关,因此推荐将其写为实例变量。举个例子,定义班级中所有学生的总数为sum
变量,更适合作为类变量。
类变量的意义:
1 | class Student(): |
类与实例变量查找顺序
对象下隐藏的内置变量__dict__
,字典里保存着对象(类或者实例)下的所有变量。优先寻找实例变量,再寻找类变量;如果类中也找不到,则会到父类中寻找。
例如:
1 | class Student(): |
student.__dict__
打印出空字典,则代表着student
实例下不存在任何变量,因此student.name
找不到任何实例变量时,进一步寻找类变量,返回同名的类变量name
。
类方法与实例方法
实例方法与self
self
不是关键字,可以用任何名称,但 python 推荐使用 self
。
实例方法,参数列表的第一个必须为self
(显式指定)。调用时不需要传入,默认传入。
self
指的是调用的实例,与类无关。
1 | class Student(): |
通常情况下,方法用于操作/计算变量,以改变特征。
实例方法的一些例子
通过上面的学习,我们知道实例方法是可以操作实例变量的。
那么,实例方法内部可以访问类变量吗?
实例方法用于
构造函数的意义在于初始化类的各个特征和行为的。
1 | class Student(): |
实例方法中访问类变量
只有在外部调用时可以,不能在内部调用时通过__dict__
查找。
1. 外部访问
1 | class Student(): |
2. 实例内部访问-方法一
1 | class Student(): |
3. 实例内部访问-方法二
可通过 self
自带的 __class__
属性
1 | class Student(): |
举个例子,下例中实现了每创建一个实例,类变量sum
就加1。
1 | class Student(): |
类方法
实例方法通常用来操作实例变量,类方法通常用于操作类变量。从上例中可以看到 __init__()
中操作了类方法,那么将其封装为一个方法,即为类方法。
类方法具有一个默认的关键字cls
(推荐使用)和@classmethod
装饰器
1 | class Student(): |
类方法和实例方法的区别:
- 实例方法关联的是实例,而类方法关联的是类本身
- 尽管实例方法也可以操作类变量,但操作与对象无关的变量时,推荐使用类方法
cls
代表调用类方法的类,上例中为Student
类
实例对象调用类方法
实例对象可以调用类方法,但不推荐这样使用。
1 | class Student(): |
静态方法
静态方法必须具有装饰器 @staticmethod
。类和实例对象均可调用静态方法。静态方法类似于类方法,但不需要传入任何指定参数。静态方法均可以用类方法代替,不推荐经常使用
静态方法和类方法的共同点在于:
- 类方法和静态方法均无法访问实例变量
静态方法和类方法的区别在于:
- 静态方法不需要显式传入
cls
- 静态方法内部可以访问类变量,由于没有
cls
,必须使用类全称调用类方法
1 | class Student(): |