• python:类4——魔法方法(定制序列、迭代)、生成器、推导式


    一、定制序列(容器类型)

    http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403:容器类型

    • 协议(Protocols)与其他编程语言中的接口很相似,它规定你哪些方法必须要定义。然而,在Python中的协议就显得不那么正式。事实上,在Python中,协议更像是一种指南。
    • 定制容器的协议
      • 如果你希望定制的容器是不可变的话,你只需要定义__len__()和__getitem__()方法                                       (str、tuple)
      • 如果你希望定制的容器是可变的话,你需要定义_len__()、__getitem__()、__setitem__()和__delitem__()方法        (list)
      • 例:编写一个不可变的自定义列表,要求记录列表中每个元素被访问的次数
      •   1 class CountList():
          2     def __init__(self, *args):
          3         self.l = [x for x in args]
          4         self.count = {}.fromkeys(range(len(self.l)), 0)
          5             
          6     def __len__(self):
          7         return len(self.l)
          8         
          9     def __getitem__(self, index):
         10         self.count[index] += 1
         11         return self.l[index]

    二、迭代

    • 定义:迭代就类似循环,每一次重复的过程称为一次迭代的过程,每一次迭代的结果将作为下一次迭代的初始值
    • 提供迭代方法的容器称为迭代器,如:list,字符串,字典
    • 通常用for i in “xx”,用于触发迭代操作;while循环实现for

    • iter()——容器对象调用iter()就得到它的迭代器
    • next()——调用next()迭代其就会返回下一个值,如果没有值可以返回了python就会抛出一个叫做StopIteration
    • In [105]: s = "fichc"
      
      In [106]: it = iter(s)
      
      In [107]: next(it)
      Out[107]: 'f'
      
      In [108]: next(it)
      Out[108]: 'i'
    • __iter__()——返回迭代器本身(对应iter()方法)
    • __next__()——决定迭代器的规则(对应next()方法)
    • Fibs数列(下一个值是前两个的和):
      1 class Fibs():
      2     def __init__(self, a, b):
      3         self.a = a
      4         self.b = b
      5     def __iter__(self):
      6         return self
      7     def __next__(self):
      8         self.a, self.b = self.b, self.a + self.b
      9         return self.a
    
    In [128]: a = test.Fibs(1, 2)
    
    In [129]: it = iter(a)
    
    In [130]: next(it)
    Out[130]: 2
    
    In [131]: next(it)
    Out[131]: 3
    
    In [121]: a = test.Fibs(1, 2)
    
    In [122]: for each in a:
         ...:     if each < 20:    #也可以把判断放到__next__(self),通过if xxx: raise StopIteration
         ...:         print(each)
         ...:     else:
         ...:         break
         ...:     
    2
    3
    5
    8
    13

    三、乱入:生成器generator

    • 迭代器和生成器是python引入的最强大的概念
    • 生成器是迭代器的一种实现,因为定义生成器需要写个类,生成器只需要一个yield
    • 生成器的发明使得python模仿协同程序的概念得以实现。协同程序就是可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始
    • 像一个会暂停,又能回来的return
    • 可以使用next()一次执行一回,也可以用for循环一次去不打印
    •   1 #coding:utf8
        2 def myGen():
        3     print('生成器被执行')
        4     yield 1
        5     yield 2
      
      In [137]: myG = test.myGen()
      In [138]: next(myG)
      生成器被执行
      Out[138]: 1                   #在yield1暂停
      In [139]: next(myG)
      Out[139]: 2                   #在yield暂停
      In [140]: next(myG)
      ---------------------------------------------------------------------------
      StopIteration                             Traceback (most recent call last)
      <ipython-input-140-bf2e9b04d728> in <module>()
      ----> 1 next(myG)
      StopIteration: 

      斐波那契数列也可以用到yield
      def libs():
      a = 0
      b = 1
      while True:
      a, b = b, a + b
      yield a
    • 列表推倒式 
    • a = [i for i in range(100) if not (i % 2) and i % 3]
      [2, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, 56, 58, 62, 64, 68, 70, 74, 76, 80, 82, 86, 88, 92, 94, 98]
    • python3还有字典推导式

    • b = {i:i % 2 == 0 for i in range(10)}
      {0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False}
    • 集合set推导式
    • In [154]: {i for i in [1,2,1,3]}
      Out[154]: {1, 2, 3}
    • 生成器推导式,可以next(e),作为函数的参数时,可以省略最外边的括号。
    • In [156]: e = (i for i in range(10))
      Out[156]: <generator object <genexpr> at 0x7fa1635bb518>

       生成器推到式若果作为函数的参数,可以直接写推导式,不用写圆括号;也可以加上

    • >>> sum(i for i in range(100) if i %2)
      2500
    • 没有元组推导式,元组推导式其实得到的就是生成器推导式;没有字符串推导式
  • 相关阅读:
    php7.1安装
    nginx 的限制连接模块limit_zone与limit_req_zone
    selinux导致docker启动失败
    docker学习笔记
    kvm虚拟机
    ZooKeeper在线迁移
    启动EMQ(emqtt)时报错找不到libsctp.so.1
    Linux Samba服务主配文件smb.conf中文详解
    python-day7-字符串类型的内置方法
    python-day7-数字类型的内置方法
  • 原文地址:https://www.cnblogs.com/daduryi/p/6737186.html
Copyright © 2020-2023  润新知