#5 Python面向对象(四)
本节将是Python面向对象的最后一篇博文了,这节将记录类的特殊方法、特殊成员方法、旧类和新类的不同,以及一些其他知识。Go!
一、类的特殊方法
Python有三种特殊方法:实例方法、静态方法、类方法。如果你读过一些源代码,你一定疑惑过这些代码:@staticmethod、@classmethod,前面见到的所有方法都是实例方法,实例方法的第一个参数为实例本身(self),由于实例方法经过前面几节已经掌握,所有本节将会熟悉剩下的两种特殊方法
静态方法
之前在类中编写的各种方法其实都是属于实例方法,每一个方法的第一个参数是实例本身(self),实例方法固然好用,但是在开发中,需要一些这样的方法:与类有关,在使用时不需要引用类和实例,也就是不能访问类变量和实例变量。这些方法通常用来作全局的配置方法,使代码更加简洁和安全。
创建静态方法
在类中的方法的前面使用装饰器: @staticmethod
即可,静态方法已经和普通函数没有太大区别,唯一的区别就是静态方法要通过对象来访问,看例:
1 | class Teacher: |
通过上例可以看到静态方法的创建比较简单,基本上已经和类无关了,按照普通的函数创建即可
调用静态方法
静态方法与函数的区别就是调用方式不同,函数直接调用即可,但是静态方法多多少少和类还是有一些关系的,那就是调用时需要对象来调用:
1 | zhangsan = Teacher('zhangsan', 'male') |
注意:静态方法无法调用类变量和实例变量,这里就不作演示了。
但是静态方法通常并不会在类外调用静态方法,而是直接在类内作为全局配置方法使用,例如:
1 | class Teacher: |
1 | # 运行结果: |
继承静态方法
如果超类中有静态方法时,子类继承时会发生什么呢?
1 | class Teacher(object): |
继承后将超类静态方法改写,运行结果j将按照子类的静态方法运行,结果如下:
1 | # 运行结果: |
类方法
类方法,顾名思义是一种直接作用于类的方法。类方法和实例方法的区别就在于:类方法只能访问类变量,不能访问实例变量。
创建类方法
在类中的方法前面使用装饰器: @classmethod
即可,类方法和实例方法格式相似,类方法第一个参数必须是类本身(cls),看例:
1 | class Teacher(object): |
通过上面代码可以看到,类方法的第一个参数为类本身,习惯上用cls表示,当然也可以用其他单词表示(这一点与self类似)
调用类方法
类方法的调用与实例方法无异,看例:
1 | zhangsan = Teacher('zhangsan', 'male') |
注意:类方法只能调用类变量,不能调用实例变量,这里就不作演示了
类方法经常出现在源代码中,通常用来为类传入新的参数。
二、类的特殊成员方法
什么事特殊成员方法呢?其实你已经见过了,那就是类似__init__这样__方法__
形式的方法
常用的特殊成员方法
__init__ 「构造函数,当实例化类对象时,会自动调用该方法」 1
2
3
4
5
6
7
8class Test:
def __init__(self):
print('实例化类对象后就会运行我')
Test()
# 运行结果:
实例化类对象后就会运行我
__del__ 「析构函数,当类对象在内存中被释放时(也就是类对象运行完后),会自动调用该方法」 1
2
3
4
5
6
7
8
9class Test:
def __del__(self):
print('类对象释放后就会运行我')
Test()
# 运行结果:
类对象释放后就会运行我
__call__ 「call方法,在类或者对象后加括号执行该方法」
1 | class Test: |
__dict__ 「dict方法,查看类或者对象的所有成员信息」 1
2
3
4
5
6
7
8
9class Test:
x = 1000
y = 'MS'
print(Test.__dict__)
# 运行结果:
{'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Test' objects>, 'x': 1000, '__doc__': None, 'y': 'MS', '__dict__': <attribute '__dict__' of 'Test' objects>}
__doc__ 「doc方法,查看类的描述信息」 1
2
3
4
5
6
7
8
9
10
11
12
13
14class Test:
'''
这里是类的描述信息
'''
x = 1000
y = 'MS'
print(Test.__doc__)
# 运行结果:
这里是类的描述信息
三、旧类与新类
Python3中,只有新类,旧类以及被移除, class 类名:
和 class 类名(object):
都是新类;Python2中, class 类名: 是旧类
, class 类名(object):
是新类
对旧类和新类了解一下即可
旧类与新类的区别
旧类:深度优先
新类:广度优先 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 在Python2中
class A:
pass
class B(A):
pass
class C(B):
pass
class D(A, B, C):
pass
D()
在Python2中,上述代码的调用顺序为:D->A->B->A->C->B->A
明显是深度优先
1 | 1 # 在Python2中 |
在Python2中,上述代码的调用顺序为:D->A->B->C->A->B->A->object
明显是广度优先
四、其他知识
私有成员和私有方法
接触类这么久了,你一定发现了又的方法和成员没有下划线,有的方法和成员只有一条下划线,有的方法和成员首尾各有两条下划线,这到底是什么含义呢?
- 无下划线 foo:表示普通方法和成员
- 一条下划线 _foo:表示被保护方法和成员,不能被 from xxx import _foo 导入
- 两条下划线 __foo:表示私有方法和成员,只运行类本身进行访问
- 首尾各两条下划线 __foo__:表示特殊方法,一般由系统自定义
结语
Python面向对象的知识到此结束,多加理解和联系才能真正掌握面向对象的知识,拜拜~