• python day5 学习整理


    今天学习的内容如下:

    1.协程函数

    2.递归

    3.匿名函数lambda

    4.内置函数(map,reduce,filter,max,min,zip,sorted)

    5.面向过程编程与函数编程

    6.模块与包的使用

    7.常用模块

    下面开始上节课的复习:

    1.函数对象(第一类对象):

    1.1 函数可以被当成数据来传递

    1.2 可以被引用

    1.3 可以当作参数传递给另一个函数

    1.4 可以当作函数的返回值

    1.5 可以当作容器类型的元素

    2.函数的嵌套

    2.1 函数的嵌套调用(在调用函数的过程中 有调用了其他的函数)

    2.2 函数的嵌套定义(在定义函数时,又实用def关键字定义了其他函数)

    3.名称空间和作用域

    3.1内置名称空间(变量的定义 都是绑定操作,都没有储值的操作)(python解释器启动的时候产生)

    3.2 全局名称空间(文件级别的)(打开文件的时候产生)

    3.3 局部名称空间(函数内部定义的名字)(调用函数的时候产生)

    3.4 全局作用域(全局名称空间和内置名称空间)

    3.5 局部作用域(局部名称空间)

    4 闭包

    4.1 定义在函数内部的函数

    4.2 该内部函数包含对外部作用域而不是对全局作用域的引用

    可以用来惰性计算

    5. 装饰器

    开放封闭原则,对修改是封闭的,对扩展是开放的

    装饰器可以是任意可调用的对象

    装饰器并不仅限于函数

    被装饰的对象也是任意可调用对象

    装饰器遵循的原则:

      不修改被装饰对象的源代码,不修改被装饰对象的调用方式

    6 迭代器

    迭代重复上次的过程,每一次迭代都是基于上一次迭代的结果继续进行

    可迭代对象:obj__iter__方法

    迭代器对象:obj__iter__ obj__next__方法

    提供了一种不需要依赖于索引的迭代方式

    for 循环的原理是 首先执行iter方法,然后用next方法去得到

    迭代器的优点和缺点:

    提供了一种不依赖于索引的迭代方式

    节省内存

    缺点:

    无法获取长度

    一次性的

    7 生成器

    函数体内包含yield,函数的执行结果是生成器对象,本质是迭代器,把函数的执行结果做成了迭代器

    返回多次值,return只能返回一次值

    可以暂停 挂起函数的执行,下一次 基于上次的执行状态继续执行

    8 内置函数

    今天上课的内容

    1.yield的语句形式: yield 1

    2.yield的表达式形式: x=yield(额外的功能,传参数)

    例子:

     1 def eater(name):
     2   print('%s ready to eat' %(name))
     3   while True:
     4       food = yield
     5      print('%s start to eat %s' %(name,food))
     6 
     7 g = eater('alex')
     8 next(g)
     9 
    10 g.send('手指头')
    11 g.send('脚趾头')

    3. 加一个装饰器,实现初始化的功能

     1 def deco(func):
     2   def wrapper(*args,**kwargs):
     3      res = func(*args,**kwargs)
     4      next(res)
     5      return res
     6   return wrapper
     7 
     8 @deco
     9 def eater(name):
    10   print('%s ready to eat' %(name))
    11   while True:
    12      food = yield
    13      print('% start eat %s' %(name,food))

    4. 模拟菜单功能

     1 def deco(func):
     2     def wrapper(*args,**kwargs):
     3         res = func(*args,**kwargs)
     4         next(res)
     5         return res
     6     return wrapper
     7 
     8 @deco
     9 def eater(name):
    10     print('%s ready to eat' %(name))
    11     food_list = []
    12     while True:
    13         food = yield food_list
    14         food_list.append(food)
    15         print('%s start eat %s' %(name,food))
    16 
    17 g = eater('alex')
    18 print(g.send('egon1'))
    19 print(g.send('egon2'))

    5. x=yield的功能

    5.1 g.send('111'),先把111传值给yield,由yield赋值给x,然后再往下执行,直到再次碰到yield,然后把yield后的返回值返回

    6. yield的应用

    例如:grep -rl 'python' /root(找到/root目录下所有文件中包含python内容的文件,把文件名返回)

     1 import os
     2 
     3 def deco(func):
     4     def wrapper(*args,**kwargs):
     5         res = func(*args,**kwargs)
     6         next(res)
     7         return res
     8     return wrapper
     9 
    10 @deco
    11 def search(target):
    12     while True:
    13         serach_path = yield
    14         g=os.walk(serach_path)
    15         for par_dir,_,files in g:
    16             for file in files:
    17                 file_abs_path=r'%s\%s' %(par_dir,file)
    18                 # print(file_abs_path)
    19                 target.send(file_abs_path)
    20 
    21 
    22 @deco
    23 def opener(target):
    24     while True:
    25         file_abs_path=yield
    26         with open(file_abs_path,encoding='utf-8') as f:
    27             target.send((file_abs_path,f))
    28 @deco
    29 def cat(target):
    30     while True:
    31         file_abs_path,f = yield
    32         for line in f:
    33             target.send((file_abs_path,line))
    34 @deco
    35 def grep(target,pattern):
    36     while True:
    37         line = yield
    38         if pattern in line:
    39             target.send(file_abs_path)
    40 
    41 @deco
    42 def printer():
    43     while True:
    44 
    45         file_abs_path = yield
    46         print(file_abs_path)
    47         
    48 g = search(opener(cat(grep(printer),'python')))
    49 g.send('/root')

    7. 面向过程的程序设计

    是一种流水线式的编程思路,是机械式的,优点是:程序的结构清晰,可以把复杂的问题简单化,明细化。缺点是:扩展性差

    应用场景:linux的内核,git,httpd都是面向过程方式写的

    8. 模块与包

    什么模块,一个py文件 就是一个模块,一个模块就是一个包含了python定义和申明的文件。

    为什么要使用模块:方便管理,实现了功能的重复利用

    引用的两种方式

    import ...

    from ... import ...(优点:不用加前缀,缺点:容易和当前的重名)

    导入模块干的事:

    1.产生新的名称空间

    2.以新建的名称空间为全局名称空间,执行文件的代码

    3.拿到一个模块名,指向导入的模块.py产生的名称空间

    spam.money(引用模块的值)

    spam.read1(拿到read1的内存地址,然后可以执行)

    import ... as ... (起别名,一行也可以导入多个,通过逗号隔开)

    从哪个文件来就以哪个文件的环境变量为准

    __all__=[](和from import * 一起使用,列表里面必须是字符串,控制导入的值)

    9. __name__

    __file__:绝对路径

    1.当作脚本执行的时候__name__ == '__main__'

    2.当作模块导入: __name__ == 模块名

    1 if __name == '__main__':
    2   print('当作脚本执行')

     10. 模块的搜索路径

    先从内存里面找,然后去内置的里面找,然后去sys.path里面去找(sys.path,就是一个列表)

    11. 包

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

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

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

    ps:包A和包B下有同名的模块也不会冲突,如A.a和B.a来自于两个命名空间

    11.1 注意事项

    1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。

    2.对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

    3.对比import item 和from item import name的应用场景:
    如果我们想直接使用name那必须使用后者

    11.2 __init__.py

    不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。

     11.3 绝对导入和相对导入

    我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

    绝对导入:以glance作为起始

    相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

    例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

    注意:在使用pycharm时,有的情况会为你多做一些事情,这是软件相关的东西,会影响你对模块导入的理解,因而在测试时,一定要回到命令行去执行,模拟我们生产环境,你总不能拿着pycharm去上线代码吧!!!

    特别需要注意的是:可以用import导入内置或者第三方模块(已经在sys.path中),但是要绝对避免使用import来导入自定义包的子模块(没有在sys.path中),应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式。

    比如我们想在glance/api/versions.py中导入glance/api/policy.py,有的同学一抽这俩模块是在同一个目录下,十分开心的就去做了,它直接这么做

    1 #在version.py中
    2 
    3 import policy
    4 policy.get()

    没错,我们单独运行version.py是一点问题没有的,运行version.py的路径搜索就是从当前路径开始的,于是在导入policy时能在当前目录下找到

    但是你想啊,你子包中的模块version.py极有可能是被一个glance包同一级别的其他文件导入,比如我们在于glance同级下的一个test.py文件中导入version.py,如下

     1 from glance.api import versions
     2 
     3 '''
     4 执行结果:
     5 ImportError: No module named 'policy'
     6 '''
     7 
     8 '''
     9 分析:
    10 此时我们导入versions在versions.py中执行
    11 import policy需要找从sys.path也就是从当前目录找policy.py,
    12 这必然是找不到的
    13 '''                                                                                                        
  • 相关阅读:
    IDETalk
    servlet概述
    过滤器(Filter)
    ieda常用快捷键
    UUID
    JRebel 7.0.10 for intellij IDEA 2017.1
    BP神经网络(手写数字识别)
    遗传算法解决TSP问题
    [CODEVS1258]关路灯
    [NOIP2007]统计数字
  • 原文地址:https://www.cnblogs.com/ybyblog/p/6952882.html
Copyright © 2020-2023  润新知