zoukankan      html  css  js  c++  java
  • 零基础学习python_魔法方法(41-48课)(迭代器)

      接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有。。。

      魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1-1.html

      啥是魔法方法呢?

     魔法方法是“面向对象”python的一切,一般被双下划线包围着,例如__init__(self[,...]);

     __init__这个是一个构造函数,在类里面一般用于属性初始化,返回值为Null,不要在__init__函数下return值。

      我们在实例化对象的时候,大部分的人会觉得调用的第一个魔法方法应该是__init__,但其实不是,第一个被调用的应该是__new__(cls[,...])(注意第一个参数是类class),返回一个实例对象,通常返回是这个class类的对象(也可以返回其它对象),举个例子看下:

    下面还有一个析构函数,也就是__del__(self),注意:当所有对这个对象的引用都被删除时(也就是最后一个引用被删除时),就会启动垃圾回收机制,就会调用__del__方法。

    注意:只有最后引用都删除了才会调用del方法!

    下面给大家简单介绍下魔法方法中属性访问:

    上面是4个类的魔法方法,下面举个例子大家看下

    class Att():
        def __getattribute__(self, name):
            print("__getattribute__")
            return super().__getattribute__(name)   #调用基类的__getattribute__
    
        def __getattr__(self, name):
            print("__getattr__")
    
        def __setattr__(self, name, value):
            print("__setattr__")
            super().__setattr__(name, value)
    
        def __delattr__(self,name):
            print("__delattr__")
            super().__delattr__(name)

    调用结果如下:

    >>> a = Att()
    >>> a.x                  #x属性之前没有,因此调用顺序如下
    __getattribute__
    __getattr__
    >>> a.x = 1            
    __setattr__
    >>> a.x               #x属性存在后,getattr就不会被调用了
    __getattribute__
    1
    >>> del a.x
    __delattr__

    描述符的介绍:

    描述符是一种具有“捆绑行为”的对象属性。访问(获取、设置和删除)它的属性时,实际是调用特殊的方法(_get_(),_set_(),_delete_())。也就是说,如果一个对象定义了这三种方法的任何一种,它就是一个描述符。 

     

    定制序列->容器

        容器类型的协议
    如果说你希望定制的容器是不可变的话,你只需要定义__len__()和__getitem__()方法。
    如果你希望定制的容器是可变的话,除了__len__()和__getitem__()方法,你还需要定义__setitem__()和__delitem__()两个方法。
    题目:定制一个列表,要求记录列表中每个元素被访问的次数。要求支持append()等原生列表的方法
    
    要求1:实现获取、设置和删除一个元素的行为(删除一个元素的时候对应的计数器也会被删除)
    要求2:增加counter(index)方法,返回index参数所指定的元素记录的访问次数
    要求3:实现append()、pop()、remove()、insert()、clear()和reverse()方法(重写这些方法的时候注意考虑计数器对应的变化)

     代码如下:

    class Countlist(list):
        def __init__(self, *args):
            super().__init__(args)
            self.count = []
            for i in args:
                self.count.append(0)
    
        def __len__(self):
            return len(self.count)
    
        def __getitem__(self, key):
            self.count[key] += 1
            return super().__getitem__(key)
    
        def __setitem__(self, key, value):
            self.count[key] += 1
            super().__setitem__(key, value)
    
        def __delitem__(self, key):
            del self.count[key]
            super().__delitem__(key)
    
        def counter(self, key):
            return self.count[key]
    
        def append(self, value):
            self.count.append(0)
            super().append(value)
    
        def pop(self, key=-1):
            del self.count[key]
            return super().pop(key)
    
        def remove(self, value):
            key = super().index(value)
            del self.count[key]
            super().remove(value)
    
        def insert(self, key, value):
            self.count.insert(key, 0)
            super().insert(key, value)
    
        def clear(self):
            self.count.clear()
            super().clear()
    
        def reverse(self):
            self.count.reverse()
            super().reverse(self)

    迭代器(迭代的容器,有例如序列、列表、元组、字典等)

    迭代操作提供了两个内置函数

    • iter() 将对象变成迭代器
    • next() 迭代器返回下一个值(如果没有值了,就会抛出异常StopIteration)

    举个例子大家看下:

    string = 'fishc'
    it = iter(string)
    while True:
        try:
            each = next(it)
            print(each)
        except StopIteration:
            break    

    结果如下:

    迭代器的魔法方法如下:

    • __iter__() (容器如果是迭代器,就必须实现__iter__这个魔法方法,返回迭代器本身,return self)
    • __next__()(决定了迭代器的规则)

    举个例子:

    
    
    题目:斐波那契数列
    
    代码如下
    class Fibl:
        def __init__(self, n = 20):
            self.a = 0
            self.b = 1
            self.n = n
        def __iter__(self):
            return self
        def __next__(self):
            self.a, self.b = self.b, self.a + self.b
            if self.a >= self.n:
                raise StopIteration
            return self.a
    结果如下:

    关于迭代器的题目:

    要求自己写一个MyRev类,功能与reversed()相同(内置函数reversed(seq)是返回一个迭代器,是序列seq的逆序显示),例如:

    代码如下:

    class MyRev:
        def __init__(self, value):
            self.value = value
            self.index = len(value)
    
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.index == 0:
                raise StopIteration
    
            self.index -= 1
            return self.value[self.index]
  • 相关阅读:
    Eclipse快捷键 10个最有用的快捷键
    Eclipse--Web项目中 .classpath、mymetadata、project文件的功用
    java.lang.IllegalStateException:Web app root system property already set to different value 错误原因及解决 Log4j
    验证位置时发生错误:“org.tigris.subversion.javahl.ClientException......
    隐藏控制台黑窗口
    APK伪加密
    格蠹汇编-01-blog
    static_cast、dynamic_cast、const_cast和reinterpret_cast总结
    CONTAINING_RECORD宏
    explicit关键字
  • 原文地址:https://www.cnblogs.com/leixiaobai/p/7978322.html
Copyright © 2011-2022 走看看