作用域:变量的访问权限
函数的里面可以访问外面,外面不能直接访问里面。
如果外面想返回里面,必须且只能通过return
的返回值实现。
def fun():
x = 123
return x
val = fun()
print(val)
关键字:
global:在局部,引入全局变量
nonlocal:在局部,引入外层的局部变量
首先了解什么是函数的调用,以代码举例如下:
def func1()
pass
def func2():
func1() # 调用函数func1
func2() # 调用函数func2
函数的嵌套则是一层套着一层
def func1():
def func2(): # 函数的嵌套,局部变量
pass
局部的东西,一般都是在局部自己访问使用的。
下面构建一个嵌套的函数,理解其执行顺序。
def func1():
print(123)
def func2():
print(456)
def func3():
print(789)
print(1)
func3()
print(2)
print(3)
func2()
print(4)
func1()
这13行代码的执行顺序分析如下,下面直接以数字表示(例如执行第3行代码就是“执行3”)
首先调用函数,执行13,就会进入func1
然后进入函数内部,执行2,最先输出执行结果:123
然后按行执行3,定义函数func2,但此时并没有调用func2,因此忽略func2的内部函数体,执行10,输出打印的内容:3
然后执行11,调用func2,因此进入func2中,即执行4,打印结果:456
然后按顺序执行5,定义函数func3,由于没有调用,则执行7,打印结果:1
然后按顺序执行8,调用函数func3,执行函数体,执行6,打印结果:789
然后按顺序执行9,打印结果:2
此时调用函数func2已经结束,继续按顺序执行12,打印结果4
最终代码执行结果如下:
123
3
456
1
789
2
4
此处的难点在于,定义函数def func()
时,不需要执行函数体内部的代码,按照行的顺序向下依次执行即可;调用函数func()
时,才会执行函数体内的代码,执行完后,退出当前函数,返回上一层函数。
def func1():
print("我是函数")
def func2(fu): # fu要求是一个函数
fu() # func1()
func2(func1)
def func():
def func_in():
print("我是函数")
return func_in
ret = func()
ret()
def func1():
print("func1")
def func2():
print("func2")
func1 = func2
func1()
本质是内层函数对外层函数局部变量的使用,此时内层函数被称为闭包函数。
它可以让一个变量常驻于内存,且避免全局变量被修改。
以下面代码举例:
def func():
a = 10
def func_in():
nonlocal a
a += 1
return a
return func_in
ret = func()
r1 = ret()
print(r1)
r2 = ret()
print(r2)
装饰器本质上是一个闭包。
在不改变原有函数调用的情况下,给函数增加新的功能。
简单来说,函数前后增加新功能,不改变源代码。
def rap(fn): # rap是装饰器,fn是目标函数
def inner():
# 在目标函数执行之前
fn() # 执行目标函数
# 在目标函数执行之后
return inner
可迭代的数据类型都会提供一个叫迭代器的东西,它可以帮助我们把数据类型中的所有数据逐一拿到。
爹迭代器本身也是可迭代的:
只能向前不能反复;
特别节省内存;
惰性机制。
获取迭代器的两个方法:
1.使用iter()
内置函数
2.使用__iter__()
特殊方法
从迭代器中拿数据
1.使用next()
内置函数
2.使用__next__()
特殊方法
举例代码说明:
it = iter("北京欢迎你")
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
或者:
it = "北京欢迎你".__iter__()
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())
for循环一定是拿迭代器的,所有不可迭代的东西不能用for循环
迭代器统一了不同数据类型的遍历工作
生成器本质是迭代器,生成器函数有一个关键字yield
生成器函数执行时,并不会执行函数,得到的是生成器
只要函数中出现了yield
,它就是一个生成器函数
作用:返回数据;分段执行函数中的的内容,通过__next__()
执行到下一个yield
的位置
优势:用好了,特别节省内存
def order():
lst = []
for i in range(1000):
lst.append(f"衣服{i}")
if len(lst) == 50:
yield lst
# 下一次拿数据
lst = []
gen = order()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())