函数(二)
一、变量的作用域
回顾:作用域泄露 (在C和C++不存在这个问题)
1 2 3 4 5 6 7
| a = 3 b = 5 if a > b: max = a else: max = b print(f"{a}和{b}中的最大值为:{max}")
|
1、全局变量
- 定义:定义在文件的顶头部分,没有任何的缩进
- 作用域/作用范围:从定义的位置开始到整个文件的结尾
1 2 3 4 5 6 7
| a = 5 b = 10 def f(): print(a,b) f()
|
2、局部变量
- 定义:在函数内部定义的变量
- 作用域/作用范围:从函数内定义变量的位置开始到函数结束
1 2 3 4 5 6 7
| def f(): a = 10 print(a)
f() print(a)
|
3、局部变量和全局变量同名
1 2 3 4 5 6 7
| a = 100 def f(): a = 200 print('1111',a)
f() print('2222',a)
|
如果全局变量与局部变量同名,则局部作用域下去访问变量时,访问到是局部变量,此时局部变量量体裁衣隐藏全局变量的值。
二、global和nonlocal
1、global关键字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| g = 100 def f(): print(g) f()
g = 100 def f(): g = 200 f() print(g)
g = 100 def f(): g += 1 f()
|
如何解决上述的问题3:
1 2 3 4 5 6 7 8
|
g = 100 def f(): global g g += 1 f() print(g)
|
2、nonlocal关键字
1 2 3 4 5 6 7 8 9 10
| a = 100 def func1(): a = 200 def func2(): a = 300 func2() print(a) func1() print(a)
|
1 2 3 4 5 6 7 8 9 10 11 12
| a = 100
def func1(): a = 200 def func2(): global a a = 300 func2() print(a)
func1() print(a)
|
- 如果要在func2中修改func1中声明的局部变量a:
1 2 3 4 5 6 7 8 9 10 11
| a = 100 def func1(): a = 200 def func2(): nonlocal a a = 300 func2() print(a)
func1() print(a)
|
nonlocal是修改外层函数中的局部变量,在下一层的作用域中去引用上一层中的局部变量
三、lambda表达式
四、闭包
在一个外函数中定义了一个内函数(内嵌函数),内函数里运用了外函数的临时变量(局部变量),并且外函数的返回值是内函数(的引用)。这样就形成了闭包closure。
1 2 3 4 5 6 7 8 9 10
| def outer(x): y = 10
def inner(): print(x+y)
return inner
f = outer(5) f()
|
1 2 3
| # 1. 必须是一个内嵌函数 # 2. 内函数引用外函数中的局部变量 # 3. 外函数要返回内函数本身
|
1 2 3
| 闭包特点: - 开辟独立的空间 - 应用:装饰器
|
当外函数调用完毕,理论来说外函数中定义的局部变量应该被释放,但是闭包中,当外函数发现内函数持有我的局部变量时,该局部变量就不会被销毁。
1 2 3 4 5 6 7 8 9 10 11 12
| def fun(): l = [] for i in range(3): def fun2(x): print(x+i) l.append(fun2) return l
for i in fun(): i(2)
|
1 2 3 4
| def fun(): return [lambda x:i*x for i in range(4)]
print([m(2) for m in fun()])
|
五、高级函数
在Python2
中是内置函数,而3中是类
filter()
1 2 3 4 5 6 7 8
| # 原型:filter(function or None, iterable) --> filter object 1. 过滤掉iterable中为False的元素,保留为真的元素 2. 返回的是一个filter对象,是可以迭代 3. 第一个参数:可以是一个函数/匿名函数,也可以是None 4. 第二个参数: 如果第一个参数是None值,则返回iterable中元素为True的值 如果第一个参数是函数,则它会将iterable中的每一个元素作为参数传递给函数,返回为真的元素 5. 第一个参数为函数时,函数的返回值必须为bool对象
|
1 2 3 4 5 6
| f = filter(None,[0,2,3,4,5,0]) print(f) print(list(f))
print(list(filter(None,[0,2,3,4,5,0])))
|
1 2 3
| for i in filter(lambda x:x==0,[0,2,3,4,5,0]): print(i)
|
1 2 3 4 5 6 7 8
| def f(x): return x % 2
for i in filter(f,[0,2,3,4,5,0]): print(i) for i in filter(lambda x:x%2,[0,2,3,4,5,0]):
|
map()
1 2 3 4
| map : 映射 # 原型:map(func, *iterables) --> map object 1. 将可变长参数(可迭代对象)每一个元素,进行两两对应后,通过第一个参数func进行计算,直到每一个元素计算完毕,返回map对象(可迭代对象) 2. 多个迭代对象,以短的为准
|
1 2
| print(list(map(lambda x,y:x+y,[1,2,3],[4,5,6])))
|
reduce()
1 2 3 4
| reduce:减少 折叠 python3: import functools # 原型:reduce(function, sequence[, initial]) -> value 1. 将序列中的每一个元素进行计算,将序列中的两两数据作为function的参数,然后将前两个的计算结果再加上第三个数据...最终得到一个结果
|
1 2 3 4 5 6
| import functools
result = functools.reduce(lambda x,y:x+y,range(1,101)) print(result)
|
1 2 3
| import functools result = functools.reduce(lambda x,y:x*y,range(1,6)) print(result)
|
1 2 3 4 5
| import functools def factorial(n): return functools.reduce(lambda x,y:x*y,range(1,n+1))
print(factorial(5))
|