一. 作用域
作用域:变量的访问权限
函数的里面可以访问外面,外面不能直接访问里面。
如果外面想返回里面,必须且只能通过return 的返回值实现。
def fun():
x = 123
return x
val = fun()
print(val)
关键字:
global:在局部,引入全局变量 nonlocal:在局部,引入外层的局部变量
二. 函数的嵌套
2-1 函数的嵌套代码执行
首先了解什么是函数的调用,以代码举例如下:
def func1()
pass
def func2():
func1()
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() 时,才会执行函数体内的代码,执行完后,退出当前函数,返回上一层函数。
2-2 函数可以作为参数传递
def func1():
print("我是函数")
def func2(fu):
fu()
func2(func1)
2-3 函数可以作为返回值进行返回
def func():
def func_in():
print("我是函数")
return func_in
ret = func()
ret()
2-4 函数名实际上就是一个变量名,都表示一个内存地址
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):
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__())
|