文章目录
- MRO算法
- 为什么不单纯使用深度优先或者广度优先
- C3算法
- 实例方法 静态方法 类方法
- 实例方法
- 静态方法
- 类方法
- 对比
- 私有属性
- python自省机制
MRO算法
为什么不单纯使用深度优先或者广度优先
- 深度优先搜寻
查找顺序是A->B->D->C, 但是如果C重载了D的某个方法(B没有重载该方法), 由于深度优先所以将会使用D中的方法, 这是不合理的
- 广度优先
查找顺序是A->B->C->D->E, 由于优先级关系, B和D的优先级高于C, 但是如果C和D中定义了同一个方法, 由于广度优先所以将会使用C中的方法, 这是不合理的
C3算法
代码语言:javascript复制class D:
pass
class E:
pass
class C(E):
pass
class B(D):
pass
class A(B, C):
pass
print(A.__mro__)
>>> (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)
代码语言:javascript复制class D:
pass
class C(D):
pass
class B(D):
pass
class A(B, C):
pass
print(A.__mro__)
>>> (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)
实例方法 静态方法 类方法
实例方法
- 可以访问实例变量和类变量
- 只能实例对象调用
静态方法
- @staticmethod
- 静态方法是不可以访问实例变量或类变量,不会主动传入self,传入什么参数才能获取到什么参数.
- 可通过实例对象或类对象调用
类方法
- @classmethod
- 类方法只能访问类变量,不能访问实例变量
- 可通过实例对象或类对象调用
- 需要传入cls参数, cls参数指向的是一开始定义的类对象(不是实例对象)
对比
- 类方法无须创建实例对象调用,所以类方法的调用较实例方法更为灵活
- 静态方法有点像附属于类对象的“工具”, 将对象的相关处理逻辑“束缚”在对象体内,这样封装得会更好些。
- 实例方法只能通过实例对象调用;类方法和静态方法可以通过类对象或者实例对象调用,如果是使用实例对象调用的类方法或静态方法,最终都会转而通过类对象调用。
- 实例方法使用最多,可以直接处理实例对象的逻辑;类方法不需要创建实例对象,直接处理类对象的逻辑;静态方法将与类对象相关的某些逻辑抽离出来,不仅可以用于测试,还能便于代码后期维护。
- 实例方法和类方法,能够改变实例对象或类对象的状态,而静态方法不能。
私有属性
代码语言:javascript复制## 私有属性
# 类中所有双下划线开头的名称如__x都会在类定义时自动变形成:_类名__x的形式
class A():
__N = 0
_M = 1 # 可以在外部调用, 只是给程序员提示
def __init__(self):
self.__N = 10 # _A__N
def read(self):
print(self.__N)
def __write(self): # _A__write
self.__N = 20
print(self.__N)
def write(self):
self.__write() # 可以在内部调用
print(dir(A))
a = A()
print(a._M)
a.read()
# a.__write() # 无法调用
a.write()
print(a._A__N) # 可以调用
a._A__write() # 可以调用
['_A__N', '_A__write', '_M', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'read', 'write']
1
10
20
20
20
python自省机制
- __dict__返回的是字典, dir返回的是列表
- __dict__查看对象的所有属性(可写属性), dir查看类本身的所有属性。
# -*- coding:utf-8 -*-
# /usr/bin/python
class Person:
name = "Person_name"
class Student(Person):
student_name = 'student_name'
def __init__(self, school_name):
self.school_name = school_name
if __name__ == "__main__":
user = Student("慕课网")
print(user.__dict__) # 通过__dict__查询属性
print(user.name)
# 通过user.name可以读取到, 但是通过__dict__无法获取的原因
# name是属于Person的属性, 并不是Student的属性, 但是使用点的时候会向上查找.
print(Student.__dict__)
print(Person.__dict__)
# 通过__dict__赋值
user.__dict__["school_addr"] = "北京市"
print(user.school_addr)
# 通过__dict__查询属性
print(user.__dict__)
# 通过dir查询属性
print(dir(user))
print(dir(Student))
print(dir(Person))