命名空间
命名空间一般分为三种
- 内置命名空间:系统自带的命名空间
- 全局命名空间:在本模块中的命名空间
- 局部命名空间:在函数内部的命名空间
取值时的查找顺序
- 在局部调用:局部命名空间>全局命名空间>内置命名空间
- 在全局调用:全局命名空间>内置命名空间
global
在局部作用域想要对全局作用域的变量进行修改的时候,要使用global关键字,对全局作用域的变量进行修改,主要针对于变量和字符串
在局部想要引用全局变量时,需要通过global关键字声明,否则局部会重新定义一个新的同名变量
nonlocal
nonlocal关键字表示对父级函数作用域的变量进行修改
该方式只可以在函数嵌套的情况下进行使用
在嵌套函数中想要引用局部变量使,需要
函数名的本质
函数名的本质就是函数的内存地址,通过函数名加圆括号可以调用函数内部的代码
函数名可以被引用,可以当作容器类型的元素,可以作为函数参数,可以作为函数返回值
闭包
内部函数包含对外部作用域而非全局作用域的变量的引用,该内部函数被称为闭包函数
inner为闭包函数
当打印 函数,closure可以看到cell字样,就是闭包函数
装饰器的基本格式
def func2(func):
def inner():
print('hello world')
func()
print('hello python')
return inner
@func2
#func1 = func2(func1)
def func1():
print('in func1')
func1()
装饰一个带有参数的函数
wraps装饰器
固定结构
关于装饰器代码的一些固定结构以及问题
迭代器
迭代是循环访问的一种方式,迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素进行访问,知道所有的元素被访问完结束,迭代器只能向前不能向后
迭代
在python中、字符串、元组、列表、字典、集合、都是可以通过迭代的方式进行访问的,这些对象叫做可迭代对象,
直观上,可以通过for语句可以访问的对象,就是可迭代对象
也可以通过isinstance(l, Iterable)
语句直接返回一个bool值,进行判断。
- 一个对象具有了iter方法就是可迭代对象。
也可以使用这种方式来对可迭代对象进行访问
str1='cbaskjn'
print('__iter__'in dir(str1))
s_iter = str1.__iter__()
print(s_iter.__next__())
print(s_iter.__next__())
print(s_iter.__next__())
print(s_iter.__next__())
str1='cbaskjnnciweodiqox'
print('__iter__'in dir(str1))
s_iter = str1.__iter__()
print(s_iter.__next__())
print(s_iter.__next__())
print(s_iter.__next__())
print(s_iter.__next__())
print(next(s_iter))
print(next(s_iter))
print(next(s_iter))
print(next(s_iter))
print(next(s_iter))
迭代器就是可迭代对象通过iter方法返回的,内部具有next方法,可以通过这个
- 可迭代对象要求内部有iter方法
-
生成器
一个包含yield关键字的函数就是一个生成器,yield具有return返回值的功能
示例代码def genrator_func1():
a = 1
print('将a赋值')
yield a
b = 2
print('将b赋值')
yield b
g1 = genrator_func1()
print(g1)
print(g1.__next__())
生成器函数执行后返回的结果是一个可迭代对象,并且函数内部代码没有执行
可以通过next的方式yield
yield关键字有两点作用
保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
- 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
- 可以使用next()函数让生成器从断店处继续执行,即唤醒生成器(函数)
生成器不会一下子在内存中生成太多的数据
卖包子案例:
def profuce():
'''生产包子'''
for i in range(1000):
yield f'生产了{i}个包子'
profuce_g = profuce()
for i in range(10):
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)
<a name="jeCQS"></a>
## 列表推导式和生成器表达式
- 把列表解析的[]换成()得到的就是生成器表达式
- 列表解析式与生成器表达式都是一种遍历的编程方式,只不过生成器表达式更加节约内存
- python不但使用迭代器协议,让for循环便的更加通用,大部分内置函数,也是使用迭代器协议访问对象的,例如,sum函数是python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以我们可以直接计算一系列值的和
**示例程序**
```python
list1 = ["eagle", "cisco", "huawei", "huasan", "a", "b", "c"]
ls = [i.upper() for i in list1 if len(i)>=3]
print(ls)
tup = [(x,y) for x in range(6) for y in range(6) if x%2==0 if y%2==1 ]
print(tup)