协议,鸭子类型,动态属性,属性查找顺序, 抽象基类,super()
在python中
单下划线 ----- protected
双下划线 ------ private
实现private的方法是python的解释器将__的变量名改了名称:
_classname__(fieldName或methodName)
一.python中的协议
1.概念:
python中,协议是一个或一组方法(魔法方法),如python的序列协议包含了__len__和__getitem__两个方法,上下文管理器协议包含了__enter__和__exit__方法
二.python中的鸭子类型
1.概念
只关注它是否实现了相应的协议,不关注它的类型
三.python的属相描述符
1.概念
属性描述符作为其他类的属性而存在,实现了魔法方法中的__get__和__set__和__delete__中的一种方法,即可成为属相描述符,
其中只实现__get__的成为非数据描述符,实现__get__和__set__方法的成为数据描述符
装饰去@property把一个方法(属性)变成为属性描述符
2.例子1(利用@property):
import numbers
class User:
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, numbers.Integral):
raise ValueError("value must be int")
self._age = value
@age.getter
def age(self):
return self._age
if __name__ == "__main__":
user = User()
user.age = 11
print(user.age)
注意:如果没有@age.getter则执行@property,如果有@age.getter就输出@age.getter下的结果
列子2(利用set,get,deleter)
import numbers
class InterField:
def __init__(self):
self._value = None
def __get__(self, instance, owner):
return self._value
def __set__(self,instance, value):
if not isinstance(value, numbers.Integral):
raise ValueError("value must be int")
def __deleter__(self, instance):
pass
class User():
age = InterField()
def go(self):
pass
if __name__ == "__main__":
user = User()
user.age = 10
print(user.age)
四.python的属性查找顺序:
1.__getattribute__和__getattr__的区别:
__getattribute__不管是否有该属性都会调用
__getattr__在查不到该属性时被调用
2.普通查找顺序:
__getattribure__
实例属性(即__init__中的)
类属性__getattr__
3.数据描述符查找顺序:
__getattribute__
描述符.__get__
实例属性(即__init__)
__getattr__
4.非数据描述符:
__getattribute__
实例属性(即__init__)
描述符.__get__
__getattr__
三.抽象基类
相当于java中的接口
import abc
class A(metaclass=abc.ABCMeta):
@abc.abstractmethod
def get(self):
pass
注意:在继承上述类A时必须实现方法get否则会报错
四.super()实际的调用顺序是按照__mro__的下一个类的方法:
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
print("B")
super().__init__()
class C(A):
def __init__(self):
print("C")
super().__init__()
class D(B, C):
def __init__(self):
print("D")
super().__init__()
print(D.__mro__)
d = D()
输出>>>>>>>>>>>>>>:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
D
B
C
A
五.迭代器
* 迭代器是访问集合内元素的一种方式, 一般用来遍历数据的
* 迭代器和以下标的访问方式不一样,迭代器是不能返回的,迭代器提供了一种惰性访问数据的方式
* 以下标的访问访问方式:getitem
* 可迭代对象和迭代器是不一样的,可迭代对象实现了魔法方法:iter, 可迭代器要实现魔法方法__iter__和__next__(from collections.abc import Iterator)
1.迭代协议:
六.生成器:
1.生成器函数:
函数中只要有yield
七.查看函数的字节码:
class InFeld():
"""
属相描述符
"""
def __init__(self):
pass
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
pass
def __delete__(self, instance):
pass
import dis
print(dis.dis(InFeld))
输出:
Disassembly of __delete__:
21 0 LOAD_CONST 0 (None)
2 RETURN_VALUE
Disassembly of __get__:
15 0 LOAD_CONST 0 (None)
2 RETURN_VALUE
Disassembly of __init__:
12 0 LOAD_CONST 0 (None)
2 RETURN_VALUE
Disassembly of __set__:
18 0 LOAD_CONST 0 (None)
2 RETURN_VALUE