• 继承-MRO
  • 类的方法
  • 元类

继承-MRO

  1. Python 类的继承有单继承 多继承
  1. class A():
  2. def a(self):
  3. print("a")
  4. class B():
  5. def b(self):
  6. print("b")
  7. class C(A):
  8. # class C(B,A):
  9. def c(self):
  10. print("c")
  11. # 使用A的方法啊
  12. super().a()
  13. if __name__ == '__main__':
  14. c = C()
  15. c.c()
  16. c.a()
  17. print(C.__mro__)
  18. """
  19. c
  20. a
  21. (<class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
  22. # (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
  23. # 可以看出 当C 继承A的 时候 也继承了A中的a方法
  24. # mro链 看出 C-A-Object
  25. """

继承查找的顺序:
- 总的来说一个类的MRO列表就是合并所有父类的MRO列表
- 子类永远在父类前面
- 如果有多个父类,会根据他们在列表中的顺序被检查
- 如果遇到多继承则按代码中继承列表顺序从左到右写
- 根据侯入度为0 来判断,每一层必须选择完才可以进入下一个

类的方法

  1. - 类方法
  2. - 是类对象的方法,在定义时需要在上方使用@classmethod进行装饰,形参是cls,表示类对象,
  3. 类对象和实力对象都是可以调用
  4. - 类实例方法
  5. - 是实例化对象的方法 只有实例对象才可以调用 形参是self 指对象对象本身
  6. - 静态方法
  7. - 是一个任意函数,在其上方使用@staticmethod 进行装饰。可以用对象直接调用
  8. - 类变量
  9. - 类变量是可以在所有实例之间共享的值,也就是说他们不是单独分配给某一个实例的
  1. class Test:
  2. num_of_instance = 0
  3. def __init__(self, name):
  4. self.name = name
  5. Test.num_of_instance += 1
  6. class Person:
  7. name = "aaa"
  8. if __name__ == '__main__':
  9. print(Test.num_of_instance)
  10. t1 = Test("cc")
  11. print(Test.num_of_instance)
  12. t2 = Test("zz")
  13. print(Test.num_of_instance)
  14. print(t1.name, t1.num_of_instance)
  15. print(t2.name, t2.num_of_instance)
  16. p1 = Person()
  17. p2 = Person()
  18. p1.name = 'bb'
  19. print(p1.name)
  20. print(p2.name)
  21. print(Person.name)
  22. 这里p1.name="bbb"是实例调用了类变量,这其实和上面第一个问题一样,就是函数传参的问题,
  23. p1.name一开始是指向的类变量name="aaa",但是在实例的作用域里把类变量的引用改变了,
  24. 就变成了一个实例变量,self.name不再引用Person的类变量name了.

元类

元类 在python中基本上我们使用到到频率非常小。也就是在orm的时候我们会用到,但是orm已经替我们做好了。元类就是创建类的东西 事实上type也是元类
image.png

https://segmentfault.com/a/1190000007255412

metaclass 实现orm的原理

  1. class Field(object):
  2. def __init__(self, name, column_type):
  3. self.name = name
  4. self.column_type = column_type
  5. def __str__(self):
  6. return '<%s:%s>' % (self.__class__.__name__, self.name)
  7. class StringField(Field):
  8. def __init__(self, name):
  9. super(StringField, self).__init__(name, 'varchar(100)')
  10. class IntegerField(Field):
  11. def __init__(self, name):
  12. super(IntegerField, self).__init__(name, 'bigint')
  13. class ModelMteaclass(type):
  14. def __new__(cls, name, bases, attrs):
  15. if name == "Model":
  16. return type.__new__(cls, name, bases, attrs)
  17. print("Fount model:%s" % name)
  18. mappings = dict()
  19. for k, v in attrs.items():
  20. if isinstance(v, Field):
  21. print('Found mapping: %s ==> %s' % (k, v))
  22. mappings[k] = v
  23. for k in mappings.keys():
  24. attrs.pop(k)
  25. attrs['__mappings__'] = mappings # 保存属性和列的映射关系
  26. attrs['__table__'] = name # 假设表名和类名一致
  27. return type.__new__(cls, name, bases, attrs)
  28. class Model(dict, metaclass=ModelMteaclass):
  29. def __init__(self, **kw):
  30. super(Model, self).__init__(**kw)
  31. def __getattr__(self, key):
  32. print(key)
  33. try:
  34. return self[key]
  35. except KeyError:
  36. raise AttributeError(r"'Model' object has no attribute '%s'" % key)
  37. def __setattr__(self, key, value):
  38. self[key] = value
  39. class Customer(Model):
  40. # 定义类的属性到列的映射:
  41. id = IntegerField('id')
  42. name = StringField('username')
  43. email = StringField('email')
  44. password = StringField('password')
  45. if __name__ == '__main__':
  46. u = Customer(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
  47. print(u.name)

python 中新类 旧类的区别

  1. #新式类
  2. class C(object):
  3. pass
  4. #经典类
  5. class B:
  6. pass
  • class 执行结果和type不一致
  • 继承搜索的顺序
    • 新: 先水平搜索,然后再向上移动。
    • 旧:先深入继承树左侧,再返回,开始找右侧
  • slots: 可以把实例属性的种类锁定到 slots 规定的范围之中。
  • getattribute