命名空间

命名空间一般分为三种

  • 内置命名空间:系统自带的命名空间
  • 全局命名空间:在本模块中的命名空间
  • 局部命名空间:在函数内部的命名空间

取值时的查找顺序

  • 在局部调用:局部命名空间>全局命名空间>内置命名空间
  • 在全局调用:全局命名空间>内置命名空间

打印出当前空间中的全部的变量

global

在局部作用域想要对全局作用域的变量进行修改的时候,要使用global关键字,对全局作用域的变量进行修改,主要针对于变量和字符串

在局部想要引用全局变量时,需要通过global关键字声明,否则局部会重新定义一个新的同名变量

nonlocal

nonlocal关键字表示对父级函数作用域的变量进行修改
该方式只可以在函数嵌套的情况下进行使用
在嵌套函数中想要引用局部变量使,需要

函数名的本质

函数名的本质就是函数的内存地址,通过函数名加圆括号可以调用函数内部的代码
函数名可以被引用,可以当作容器类型的元素,可以作为函数参数,可以作为函数返回值

闭包

内部函数包含对外部作用域而非全局作用域的变量的引用,该内部函数被称为闭包函数
image.png
inner为闭包函数
当打印 函数,closure可以看到cell字样,就是闭包函数

装饰器的基本格式

  1. def func2(func):
  2. def inner():
  3. print('hello world')
  4. func()
  5. print('hello python')
  6. return inner
  7. @func2
  8. #func1 = func2(func1)
  9. def func1():
  10. print('in func1')
  11. func1()

装饰一个带有参数的函数

image.png
对于动态参数也一样

wraps装饰器

image.png

固定结构

image.png

关于装饰器代码的一些固定结构以及问题

迭代器

迭代是循环访问的一种方式,迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素进行访问,知道所有的元素被访问完结束,迭代器只能向前不能向后

迭代

在python中、字符串、元组、列表、字典、集合、都是可以通过迭代的方式进行访问的,这些对象叫做可迭代对象,
直观上,可以通过for语句可以访问的对象,就是可迭代对象
也可以通过isinstance(l, Iterable)语句直接返回一个bool值,进行判断。

  • 一个对象具有了iter方法就是可迭代对象。

也可以使用这种方式来对可迭代对象进行访问

  1. str1='cbaskjn'
  2. print('__iter__'in dir(str1))
  3. s_iter = str1.__iter__()
  4. print(s_iter.__next__())
  5. print(s_iter.__next__())
  6. print(s_iter.__next__())
  7. print(s_iter.__next__())
  8. str1='cbaskjnnciweodiqox'
  9. print('__iter__'in dir(str1))
  10. s_iter = str1.__iter__()
  11. print(s_iter.__next__())
  12. print(s_iter.__next__())
  13. print(s_iter.__next__())
  14. print(s_iter.__next__())
  15. print(next(s_iter))
  16. print(next(s_iter))
  17. print(next(s_iter))
  18. print(next(s_iter))
  19. print(next(s_iter))

迭代器就是可迭代对象通过iter方法返回的,内部具有next方法,可以通过这个

  • 可迭代对象要求内部有iter方法
  • 迭代器对象要求内部有next方法

    生成器

    一个包含yield关键字的函数就是一个生成器,yield具有return返回值的功能
    示例代码

    1. def genrator_func1():
    2. a = 1
    3. print('将a赋值')
    4. yield a
    5. b = 2
    6. print('将b赋值')
    7. yield b
    8. g1 = genrator_func1()
    9. print(g1)
    10. print(g1.__next__())

    生成器函数执行后返回的结果是一个可迭代对象,并且函数内部代码没有执行
    可以通过next的方式

    yield

    yield关键字有两点作用

  • 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起

  • 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
  • 可以使用next()函数让生成器从断店处继续执行,即唤醒生成器(函数)

生成器不会一下子在内存中生成太多的数据
卖包子案例:

  1. def profuce():
  2. '''生产包子'''
  3. for i in range(1000):
  4. yield f'生产了{i}个包子'
  5. profuce_g = profuce()
  6. for i in range(10):
  7. print(next(profuce_g))

send

send获取下一个值的效果和next方法一致
send关键字的作用

  • 触发生成器珊瑚继续只想,知道遇到哦下一个yield故拿剪子
  • 向yield出发送数据,该数据可以在yield关键字出接收 ```python def generator_send(): print(123) content = yield 1 print(‘=’*8,content) print(456) yield 2

g = generatorsend() ret = g._next() print(‘‘,ret) ret = g.send(input(‘输入想说的话’)) print(‘‘,ret)

  1. <a name="jeCQS"></a>
  2. ## 列表推导式和生成器表达式
  3. - 把列表解析的[]换成()得到的就是生成器表达式
  4. - 列表解析式与生成器表达式都是一种遍历的编程方式,只不过生成器表达式更加节约内存
  5. - python不但使用迭代器协议,让for循环便的更加通用,大部分内置函数,也是使用迭代器协议访问对象的,例如,sum函数是python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以我们可以直接计算一系列值的和
  6. **示例程序**
  7. ```python
  8. list1 = ["eagle", "cisco", "huawei", "huasan", "a", "b", "c"]
  9. ls = [i.upper() for i in list1 if len(i)>=3]
  10. print(ls)
  11. tup = [(x,y) for x in range(6) for y in range(6) if x%2==0 if y%2==1 ]
  12. print(tup)