对象名称空间

obj.name 会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类…最后都找不到就抛出异常

对象的组合用法

  1. class Weapon:
  2. def prick(self, obj): # 这是该装备的主动技能,扎死对方
  3. obj.life_value -= 500 # 假设攻击力是500
  4. class Person: # 定义一个人类
  5. role = 'person' # 人的角色属性都是人
  6. def __init__(self, name):
  7. self.name = name # 每一个角色都有自己的昵称;
  8. self.weapon = Weapon() # 给角色绑定一个武器;

面向对象三大特征

继承

  1. class Animal:
  2. def __init__(self, name, kind):
  3. self.name = name
  4. self.kind = kind
  5. def eat(self, food):
  6. print(f'{self.name} is eating {food}')
  7. class Cat(Animal):
  8. def __init__(self, name, kind, eye_color):
  9. super().__init__(name,kind) # 第二种方法,使用super().__init__()方法,相当于执行了父类的init方法
  10. # super(Cat,self).__init__(name,kind)
  11. self.eye_color = eye_color # 派生属性

当类是经典类时,多继承情况下, 会按照深度优先的方式查找
当类是新式类时,多继承情况下, 会按照广度优先方式查找
MRO 是通过 c3线下算法实现的。

多态

封装

私有变量双下滑线和单下划线

单下划线:继承子类也可以访问
双下划线:会自动变更变量和方法名 class A: key=’a’ => A._Akey

实例attribute增加除访问与修改之外的其他处理逻辑,比如类型检查或合法性验证

  1. # 不建议使用property,使得代码变得臃肿,执行变慢
  2. class Person:
  3. def __init__(self, first_name):
  4. self.first_name = first_name
  5. @property
  6. def first_name(self):
  7. return self._first_name
  8. @first_name.setter
  9. def first_name(self, value):
  10. self._first_name = value
  11. # 增加额外的操作,验证输入值类型,不让删除
  12. class Person:
  13. def __init__(self, first_name):
  14. self._first_name = first_name
  15. # Getter function
  16. @property
  17. def first_name(self):
  18. return self._first_name
  19. # Setter function
  20. @first_name.setter
  21. def first_name(self, value):
  22. if not isinstance(value, str):
  23. raise TypeError('Expected a string')
  24. self._first_name = value
  25. # Deleter function (optional)
  26. @first_name.deleter
  27. def first_name(self):
  28. raise AttributeError("Can't delete attribute")

在子类中调用父类的某个已经被覆盖的方法 super。

  • 子类调用父类已覆盖的方法
  • 函数的一个常见用法是在 init() 方法中确保父类被正确的初始化了

MRO算法:

  1. - 子类会先于父类被检查
  2. - 多个父类会根据它们在列表中的顺序被检查
  3. - 如果对下一个类存在两个合法的选择,选择第一个父类

定义描述器,强制定义实例属性类型