美文网首页
02Python学习笔记之二.六【生成器、pdb调试】2019-

02Python学习笔记之二.六【生成器、pdb调试】2019-

作者: 平知 | 来源:发表于2019-08-18 19:06 被阅读0次
    章节号 内容            
    1图片格式(png) 宽度大于620px,保持高宽比减低为620px
    1-1 应用
    1-1-1 方法

    第1章节  生成器

    • 1-1 生成器—生成器的2种方式

      列表生成式:

    In [17]: a=[x for x in range(10)]
    
    In [18]: a
    Out[18]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    In [21]: a=[x*2 for x in range(10)]
    
    In [22]: a
    Out[22]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    

      什么是生成器:
      1、把列表生成式的[]改为()

    In [25]: b=(x*2 for x in range(10))
    
    In [26]: b
    Out[26]: <generator object <genexpr> at 0x7fbf76db3eb8>
    

      怎么来使用?使用next(生成器名),一次一个。

    In [27]: next(b)
    Out[27]: 0
    
    In [28]: next(b)
    Out[28]: 2
    
    In [36]: next(b)
    Out[36]: 18
    
    In [37]: next(b)
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-37-adb3e17b0219> in <module>()
    ----> 1 next(b)
    
    StopIteration: 
    

      斐波那契数列问题。
      2、使用yield
      引言,两数交换问题。

    In [38]: a,b=0,1
    
    In [39]: a,b=b,a
    
    In [40]: a
    Out[40]: 1
    
    In [41]: b
    Out[41]: 0
    
    In [42]: a=9
    
    In [43]: b=10
    
    In [44]: a=a+b
    
    In [45]: b=a-b
    
    In [46]: a=a-b
    
    In [47]: a
    Out[47]: 10
    
    In [48]: b
    Out[48]: 9
    

      ↓这里使用列表的方式来实现斐波那契数列的计算。

    def fab(n):
        a = [1, 1]
        
        for i in range(n):
            an = a[i]+a[i+1]
            a.append(an)
            # yield a
        print(a)
    
    fab(10)
    # c=fab(10)
    # print(next(c))
    
    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
    

      ↓用yield实现:

    def fab(n):
        a = [1, 1]
        
        for i in range(n):
            an = a[i]+a[i+1]
            a.append(an)
            yield a
        print(a)
    
    print(fab(10))
    c=fab(10)
    print(next(c))
    
    <generator object fab at 0x7f7f94fff1a8>
    [1, 1, 2]
    

      ↑函数体内一旦声明了yield,此函数就会变成一个生成器。不再能被以普通的方式调用。
      1、首先要把函数赋给一个变量c=fab(10)
      2、使用next(c)来取生成器的值,或者a=c.__next__()来调用函数取得返回值。
      3、你yield谁,使用next()的时候,就返回谁。
      4、一般都是套在循环中,next()一次,执行一次循环。
      5、程序每次停在yield结束处,下一次next()从yield的下一句开始执行

    In [4]: def fab(n):
       ...:     a = [1, 1]
       ...:     
       ...:     for i in range(n):
       ...:         an = a[i]+a[i+1]
       ...:         a.append(an)
       ...:         print("before yield")
       ...:         yield a
       ...:         print("after yield")
       ...:     print(a)
       ...: 
       ...: print(fab(10))
       ...: c=fab(10)
       ...: 
    <generator object fab at 0x7fb98914dfa0>
    
    In [5]: next(c)
    before yield
    Out[5]: [1, 1, 2]
    
    In [6]: next(c)
    after yield
    before yield
    Out[6]: [1, 1, 2, 3]
    
    

      如果没有循环会咋样呢?只能生成一次~

    In [1]: def fab():
       ...:     a=0
       ...:     b=1
       ...:     c=a+b
       ...:     yield c
       ...: 
       ...: 
       ...: print(fab())
       ...: a=fab()
       ...: 
    <generator object fab at 0x7fb98a1f65f0>
    
    In [2]: next(a)
    Out[2]: 1
    
    In [3]: next(a)
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-3-15841f3f11d4> in <module>()
    ----> 1 next(a)
    
    
    • 1-2 生成器—自动输出生成器返回值,不报错

    def fab(n):
        a = [1, 1]
        
        for i in range(n):
            an = a[i]+a[i+1]
            a.append(an)
            # print("before yield")
            yield a
            # print("after yield")
        # print(a)
    
    for t in fab(10):
        print(t)
    
    
    [1, 1, 2]
    [1, 1, 2, 3]
    [1, 1, 2, 3, 5]
    [1, 1, 2, 3, 5, 8]
    [1, 1, 2, 3, 5, 8, 13]
    [1, 1, 2, 3, 5, 8, 13, 21]
    [1, 1, 2, 3, 5, 8, 13, 21, 34]
    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
    

      ↑一个生成器,可以中for循环来输入,放到in的后面即可。

    • 1-3 生成器—send

    In [14]: def test():
        ...:     i=0
        ...:     while i<5:
        ...:         t = yield i
        ...:         print(t)
        ...:         i+=1
        ...: 
        ...: t1=test()
        ...: 
    
    In [15]: next(t1)
    Out[15]: 0
    
    In [16]: next(t1)
    None
    Out[16]: 1
    
    In [17]: t1.send("hhhhh")
    hhhhh
    Out[17]: 2
    
    In [18]: next(t1)
    None
    Out[18]: 3
    
    In [19]: t1.send("jjjjjjj")
    jjjjjjj
    Out[19]: 4
    

      ↑yield i本身是没有值的,一旦使用了send()函数,则相当于给yield i发送了一个值,这个值就会赋值给t,从而被打印出来。
      ↓send()next()都可以让程序往下走一步。第一次不能使用send()

    In [21]: def test():
        ...:     i=0
        ...:     while i<5:
        ...:         t = yield i
        ...:         print(t)
        ...:         i+=1
        ...: 
        ...: t1=test()
        ...: 
    
    In [22]: t1.send("1123")
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-22-fb04f94f864c> in <module>()
    ----> 1 t1.send("1123")
    
    TypeError: can't send non-None value to a just-started generator
    
    

      ↓非要使用,则必须传递一个None

    In [25]: def test():
        ...:     i=0
        ...:     while i<5:
        ...:         t = yield i
        ...:         print(t)
        ...:         i+=1
        ...: 
        ...: t1=test()
        ...: 
    
    In [26]: t1.send(None)
    Out[26]: 0
    
    
    In [27]: def test():
        ...:     i=0
        ...:     while i<5:
        ...:         if i==0:
        ...:             temp = yield i
        ...:         else:
        ...:             yield i
        ...:         i+=1
        ...:         print(temp)
        ...: 
        ...: t=test()
        ...: 
    
    In [28]: next(t)
    Out[28]: 0
    
    In [29]: t.send("hahah")
    hahah
    Out[29]: 1
    
    In [30]: next(t)
    hahah
    Out[30]: 2
    
    In [31]: next(t)
    hahah
    Out[31]: 3
    
    In [32]: next(t)
    hahah
    Out[32]: 4
    
    In [33]: next(t)
    hahah
    
    

      ↑如果yield这里有了一个赋值的操作,那么如果不使用send给yield x发送一个值,那么yield x就会产生一个None,从而给等号左边的变量赋值一个None,那么完全可以控制好程序的走向,从而把send()出去的值一直保留下来?这有什么用呢????????????

    • 1-4 生成器—完成多任务

      yield不是暂停的概念,而是本轮执行结束的概念。我结束了,那执行流就交给下一行代码。我等待下一次执行。

    import time
    def t1():
        while True:
            print("t1")
            yield None
    
    def t2():
        while True:
            print("t2")
            yield None
    
    
    t11=t1()
    t22=t2()
    
    while True:
        t11.__next__()
        t22.__next__()
        time.sleep(1)
    
    t1
    t2
    t1
    t2
    t1
    t2
    t1
    t2
    t1
    t2
    t1
    t2
    t1
    t2
    

      ↑实现的效果就是t1和t2看上去同时执行。这就叫!!协程!!
      多任务分:进程、线程、协程

    第2章节  pdb调试(命令行)

      如何开启调试

    python3 -m pdb 名字.py
    

      交互调试,进入python或ipython解释器

    import pdb
    
    

      调试命令:
      1、l 。显示当前代码list(不好使敲个n,再l)。
      2、n。 向下执行一行next(不进入函数)。
      3、c。 直接执行完毕continue。
      4、b 空格 行数。在制定行数加断点。
      5、b。查看断点序号。
      6、clear 断点序号。删除断点。
      7、s。执行进入函数。
      8、p 变量。查看变量数据。
      9、a。查看函数内参数。
      10、

      ↓小写字母l,查看执行流位置

    li@li-System-Product-Name:~/py$ python3 -m pdb 2.py
    > /home/li/py/2.py(1)<module>()
    -> class person(object):
    (Pdb) l
      1  -> class person(object):
      2         def __init__(self, name, age):
      3             self.__name = name
      4             self.__age = age
      5     
      6         def chaname(self, name):
      7             self.__name = name
      8     
      9         def chaage(self, age):
     10             if age <=100:
     11                 self.__age = age
    (Pdb) 
    

      ↓小写字母n,执行一步

    (Pdb) n
    > /home/li/py/2.py(25)<module>()
    -> ren = person("xiaom", 14)
    (Pdb) 
    

      ↓再l看一下

    (Pdb) l
     20             print(self.__age)
     21     
     22         def getname(self):
     23             return self.__name
     24     
     25  -> ren = person("xiaom", 14)
     26     ren.priname()
     27     ren.priage()
     28     
     29     ren.chaname("aaa")
     30     ren.chaage(1111)
    (Pdb) 
    

      ↓c,直接执行完毕

    li@li-System-Product-Name:~/py$ python3 -m pdb 2.py
    > /home/li/py/2.py(1)<module>()
    -> class person(object):
    (Pdb) c
    xiaom
    14
    输入的年纪非法
    aaa
    14
    The program finished and will be restarted
    > /home/li/py/2.py(1)<module>()
    -> class person(object):
    
    

      ↓b空格7,回车,c。设断点,执行到断点。

    (Pdb) b 6
    Breakpoint 1 at /home/li/py/2.py:6
    (Pdb) c
    > /home/li/py/2.py(6)person()
    -> def chaname(self, name):
    (Pdb) l
      1     class person(object):
      2         def __init__(self, name, age):
      3             self.__name = name
      4             self.__age = age
      5     
      6 B->     def chaname(self, name):
      7             self.__name = name
      8     
      9         def chaage(self, age):
     10             if age <=100:
     11                 self.__age = age
    (Pdb) 
    
    • 2-1 pdb调试—







    • 3-1 类的初步—定义一个类并创建对象实例

      ↑↓类的基本结构:

    • 1-1 类的初步—定义一个类并创建对象实例

      1-1-1. 导言—用户管理—用户的分类及介绍
    • 1-2 类的初步—定义一个类并创建对象实例

      1-2-1. 导言—用户管理—用户的分类及介绍

    第2章节 

    • 2-1 类的初步—定义一个类并创建对象实例

      2-1-1. 导言—用户管理—用户的分类及介绍
    • 2-2 类的初步—定义一个类并创建对象实例

      2-2-1. 导言—用户管理—用户的分类及介绍

    第3章节 

    • 3-1 类的初步—定义一个类并创建对象实例

      3-1-1. 导言—用户管理—用户的分类及介绍
    • 3-2 类的初步—定义一个类并创建对象实例

      3-2-1. 导言—用户管理—用户的分类及介绍

    相关文章

      网友评论

          本文标题:02Python学习笔记之二.六【生成器、pdb调试】2019-

          本文链接:https://www.haomeiwen.com/subject/mfqdsctx.html