迭代器协议和描述符

迭代器协议

__next__和__iter__实现迭代器协议
什么是迭代器协议:对象必须提供一个next方法,执行该方法要哦返回迭代中的下一项,要么就引起一个stopiteration异常,来终止迭代
iter的功能就是把你的一个对象变成可迭代对象,所以类当中必须要有一个iter方法

class Foo:
    def __init__(self,n):
        self.n = n
    def __iter__(self):
        return self
    def __next__(self):
        if self.n ==12:
            raise StopIteration('太多了,停止了')
        self.n+=1
        return self.n
f1 = Foo(10)
print(f1.__next__())
print(f1.__next__())
# f1 = Foo()
for i in f1: #iter(f1)===>f1.__iter__()
    print(i)#之前也谈到过for循环会捕捉到Stopiteration异常然后终止掉

斐波那契数:后面那个数是前两个数之和,用迭代器协议实现斐波那契数:

class Fib:
    def __init__(self):
        self._a = 1
        self._b = 1
    def __iter__(self):
        return self
    def __next__(self):
        if self._a>100:
            raise StopIteration('stop')
        self._a,self._b = self._b,self._a+self._b
        return self._a
f1 = Fib()
print(next(f1))
print(next(f1))
print(next(f1))
for t in f1:
    print('111111111111111')
    print(t)

描述符:

描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议

class Foo:
    def __get__(self, instance, owner):
        print('get')
    def __set__(self, instance, value):
        print('set')
    def __delete__(self, instance):
        print('delete方法')

#描述符的作用是在代理另外一个属性的(必须把描述符定义成为这个类的类属性,不能定义到构造函数中)

class Bar:
    x = Foo()
b1 = Bar()
b1.x#必须是其他类调用时才会触发
b1.x = 1#同理
del b1.x#同理

#数据描述符:至少实现了__get__()__set__()
#非数据描述符:没有__set__()

注意:

1、描述符本身应该定义成新式类,被代理的类也应该是新式类
2、必须把描述符定义成另外一个类的雷属性,不能赢一到构造函数中

2的意思就是:

class Qqq:
    q = Foo()#这个没问题
    def __init__(self):
        self.y = Foo()

这个就不叫描述符,对Y的修改不会触发Foo__get__与__set__方法

3、要严格遵循以下优先级,由高到低分别为:

1.类属性
2.数据描述符
3.实例属性
4.非数据描述符
5.找不到的属性触发__getattr__()

class Foo:
    def __get__(self, instance, owner):
        print('get')
    def __set__(self, instance, value):
        print('set')
    def __delete__(self, instance):
        print('delete方法')

类属性的优先级最高,之前x对应着上一个类的描述符,那么现在就覆盖了,所以和描述符就没关系了

class Bar:
    x= Foo()
Bar.x = 1
print(Bar.x)

所以调用出来就是1,不会触发描述符
实力属性>非数据描述符(没有set方法):

class Foo:
    def __get__(self, instance, owner):
        print('get')
class Bar:
    x = Foo()
b1 = Bar()
b1.x = 1
print(b1.__dict__)

输出:{‘x’: 1},实力属性比非数据描述符优先级要高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值