• python-学习 协程函数 模块与包


     一、协程函数  

     yield的用法:

    1:把函数的执行结果封装好__iter__和__next__,即得到一个迭代器
    2:与return功能类似,都可以返回值,但不同的是,return只能返回一次值,而yield可以返回多次值
    3:函数暂停与再继续运行的状态是有yield保存
     1 # 例子1
     2 # def chi(name):
     3 #     print('%s 开始上菜啦~'%name)
     4 #     cd=[]     #菜单
     5 #     while True:
     6 #         food=yield cd
     7 #         cd.append(food)
     8 #         print('%s上了一份%s'%(name,food))
     9 #         print(cd)
    10 # esa=chi('alex')
    11 # esa.send('芹菜')
    12 # 例子2
    13 # def chi(name):
    14 #     print('%s 开始上菜啦~'%name)
    15 #     cd=[]     #菜单
    16 #     while True:
    17 #         food=yield cd
    18 #         cd.append(food)
    19 #         print('%s上了一份%s'%(name,food))
    20 # def shui():
    21 #     name = input('服务员名字>>: ').strip()
    22 #     while True:
    23 #         food=input('菜名>>: ').strip()
    24 #         sc=chi(name)
    25 #         next(sc)#初始化:就是让函数执行停到yield
    26 #         if not food or not name :continue
    27 #         sc.send(food)#给yield传值
    28 # shui()
    例子

      通过装饰器初始化:

     1 def chushi(func):
     2     def hua(*args,**kwargs):
     3         g=func(*args,**kwargs)
     4         next(g)
     5         return g
     6     return hua
     7 @chushi
     8 def chi(name):
     9     print('%s 开始上菜啦~'%name)
    10     cd=[]     #菜单
    11     while True:
    12         food=yield cd
    13         cd.append(food)
    14         print('%s上了一份%s'%(name,food))
    15         print(cd)
    16 esa=chi('alex')
    17 esa.send('芹菜')
    18 
    19 
    20 
    21 #例子2
    22 # def chushi(func):
    23 #     def hua(*args,**kwargs):
    24 #         g=func(*args,**kwargs)
    25 #         next(g)
    26 #         return g
    27 #     return hua
    28 # @chushi
    29 # def chi(name):
    30 #     print('%s 开始上菜啦~'%name)
    31 #     cd=[]     #菜单
    32 #     while True:
    33 #         food=yield cd
    34 #         cd.append(food)
    35 #         print('%s上了一份%s'%(name,food))
    36 # def shui():
    37 #     name = input('服务员名字>>: ').strip()
    38 #     while True:
    39 #         food=input('菜名>>: ').strip()
    40 #         sc=chi(name)
    41 #         # next(sc)#初始化:就是让函数执行停到yield
    42 #         if not food or not name :continue
    43 #         sc.send(food)#给yield传值
    44 # shui()
    例子

    二、面向过程编程

    面向过程:核心是过程二字,过程即解决问题的步骤,基于面向过程去设计程序就像是在设计
    一条工业流水线,是一种机械式的思维方式
    优点:程序结构清晰,可以把复杂的问题简单化,流程化
    缺点:可扩展性差,一条流线只是用来解决一个问题
    应用场景:linux内核,git,httpd,shell脚本

     1 import os
     2 def init(func):
     3     def wrapper(*args,**kwargs):
     4         g=func(*args,**kwargs)
     5         next(g)
     6         return g
     7     return wrapper
     8 
     9 #第一阶段:找到所有文件的绝对路径
    10 @init
    11 def search(target):
    12     while True:
    13         filepath=yield
    14         g=os.walk(filepath)
    15         for pardir,_,files in g:
    16             for file in files:
    17                 abspath=r'%s\%s' %(pardir,file)
    18                 target.send(abspath)
    19 # search(r'C:UsersAdministratorPycharmProjectspython18期周末班day5aaa')
    20 # g=search()
    21 # g.send(r'C:Python27')
    22 
    23 #第二阶段:打开文件
    24 @init
    25 def opener(target):
    26     while True:
    27         abspath=yield
    28         with open(abspath,'rb') as f:
    29             target.send((abspath,f))
    30 
    31 
    32 
    33 
    34 #第三阶段:循环读出每一行内容
    35 @init
    36 def cat(target):
    37     while True:
    38         abspath,f=yield #(abspath,f)
    39         for line in f:
    40             res=target.send((abspath,line))
    41             if res:break
    42 
    43 
    44 
    45 #第四阶段:过滤
    46 @init
    47 def grep(pattern,target):
    48     tag=False
    49     while True:
    50         abspath,line=yield tag
    51         tag=False
    52         if pattern in line:
    53             target.send(abspath)
    54             tag=True
    55 
    56 
    57 #第五阶段:打印该行属于的文件名
    58 @init
    59 def printer():
    60     while True:
    61         abspath=yield
    62         print(abspath)
    63 
    64 g = search(opener(cat(grep('os'.encode('utf-8'), printer()))))
    65 # g.send(r'C:UsersAdministratorPycharmProjectspython18期周末班day5aaa')
    66 
    67 g.send(r'C:UsersAdministratorPycharmProjectspython18期周末班')
    68 #a1.txt,a2.txt,b1.txt
    grep -rl 'error' /dir/

    三、递归与二分法

      递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身

     1 #直接
     2 # def func():
     3 #     print('from func')
     4 #     func()
     5 #
     6 # func()
     7 
     8 #间接
     9 # def foo():
    10 #     print('from foo')
    11 #     bar()
    12 #
    13 # def bar():
    14 #     print('from bar')
    15 #     foo()
    16 #
    17 # foo()
    例子 

      递归的执行分为两个阶段:
        1 递推
        2 回溯

     1  l =[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]]
     2 
     3  def search(l):
     4      for item in l:
     5          if type(item) is list:
     6              search(item)
     7          else:
     8              print(item)
     9 
    10  search(l)
    例子

      二分法

     1 #例子1
     2  l = [1,2,5,7,10,31,44,47,56,99,102,130,240]
     3 
     4 
     5  def binary_search(l,num):
     6      print(l) [10, 31]
     7      if len(l) > 1:
     8          mid_index=len(l)//2 1
     9          if num > l[mid_index]:
    10              in the right
    11              l=l[mid_index:] l=[31]
    12              binary_search(l,num)
    13          elif num < l[mid_index]:
    14              in the left
    15              l=l[:mid_index]
    16              binary_search(l,num)
    17          else:
    18              print('find it')
    19      else:
    20          if l[0] == num:
    21              print('find it')
    22          else:
    23              print('not exist')
    24          return
    25 
    26  binary_search(l,32)
    27 
    28 
    29 
    30 
    31 
    32 
    33 
    34 
    35 
    36 
    37 
    38 
    39 
    40 
    41 
    42 
    43 
    44 #例子2
    45 l = [1,2,5,7,10,31,44,47,56,99,102,130,240]
    46 
    47 
    48 def binary_search(l,num):
    49     print(l)
    50     if len(l) == 1:
    51         if l[0] == num:
    52             print('find it')
    53         else:
    54             print('not exists')
    55         return
    56     mid_index=len(l)//2
    57     mid_value=l[mid_index]
    58     if num == mid_value:
    59         print('find it')
    60         return
    61     if num > mid_value:
    62         l=l[mid_index:]
    63     if num < mid_value:
    64         l=l[:mid_index]
    65     binary_search(l,num)
    66 
    67 binary_search(l,32)
    例子

    四、模块与包

     1.模块只在第一次导入时才会执行,之后的导入都是直接引用内存已经存在的结果

       模块搜索路径:  
       内存中--》内置模块————》sys.path

      注意:自定义的模块名一定不要与python自带的模块名重名

     2.什么是模块

         常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。

       但其实import加载的模块分为四个通用类别: 

      1 使用python编写的代码(.py文件)

      2 已被编译为共享库或DLL的C或C++扩展

      3 包好一组模块的包

      4 使用C编写并链接到python解释器的内置模块

     3.import的导入

     1 #spam.py
     2 print('from the spam.py')
     3 
     4 money=1000
     5 
     6 def read1():
     7     print('spam->read1->money',money)
     8 
     9 def read2():
    10     print('spam->read2 calling read')
    11     read1()
    12 
    13 def change():
    14     global money
    15     money=0
    span.py

    导入span模块

    1 #test.py
    2 import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
    3 import spam
    4 import spam
    5 import spam
    6  '''
    7  执行结果:
    8  from the spam.py
    9  '''
    例子

    可以使用__all__来控制*(用来发布新版本)

    在spam.py中新增一行

    __all__=['money','read1'] #这样在另外一个文件中用from spam import *就这能导入列表中规定的两个名字

      4.rom.......import的导入

        优点:使用源文件内的名字时无需加前缀,使用方便
        缺点:容易与当前文件的名称空间内的名字混淆

     

      5.绝对导入和相对导入

    1 在glance/api/version.py
    2 
    3 #绝对导入
    4 from glance.cmd import manage
    5 manage.main()
    6 
    7 #相对导入
    8 from ..cmd import manage
    9 manage.main()
    例子

    1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

    2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

    3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

    强调:

      1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

      2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

  • 相关阅读:
    JavaMail
    Web的文件下载
    Web的文件上传
    Tcp 数据对象传输接口对象设计
    m个元素中选取n的组合
    PyQT Quick Start
    版本发布自动触发测试
    plantUML 实操
    Python 版本对比
    Some Python Tricks
  • 原文地址:https://www.cnblogs.com/ikere/p/7280145.html
Copyright © 2020-2023  润新知