文章目录
- lambda 表达式和匿名函数
- eval()函数
- 函数嵌套(内部函数)
- 什么情况需要使用内部函数
- nonlocal关键字
- LEGB 规则
lambda 表达式和匿名函数
lambda 表达式可以用来声明匿名函数。lambda 函数是一种简单的、在同一行中定义函数的方法。lambda 函数实际生成了一个函数对象。lambda 表达式只允许包含一个表达式,不能包含复杂语句,该表达式的计算结果就是函数的返回值。(有点像scala中的表达)
lambda 表达式的基本语法如下:
lambda arg1,arg2,arg3...:<表达式>
arg1/arg2/arg3 为函数的参数。<表达式>相当于函数体。运算结果是:表达式的运算结果。
f = lambda a,b,c:a+b+c
print(f)
print(f(2,3,4))
g = [lambda a:a*2,lambda b:b*3,lambda c:c*4]
print(g[0](6), g[1](7), g[2](8))
# 使用lambda对列表进行操作
li = [1, 2, 3, 4, 5]
# 序列中的每个元素加1
map(lambda x: x+1, li) # [2,3,4,5,6]
# 返回序列中的偶数
filter(lambda x: x % 2 == 0, li) # [2, 4]
# 返回所有元素相乘的结果
reduce(lambda x, y: x * y, li) # 1*2*3*4*5 = 120
eval()函数
功能:将字符串 str 当成有效的表达式来求值并返回计算结果。可以在程序不中断运行时实现代码的动态加载(类似java中的动态加载)。
语法:
eval(source[, globals[, locals]]) -> value
参数:
- source:一个 Python 表达式或函数 compile()返回的代码对象
- globals:可选。必须是 dictionary
- locals:可选。任意映射对象
#测试 eval()函数
s = "print('abcde')"
eval(s)
a = 10
b = 20
c = eval("a+b")print(c)
dict1 = dict(a=100,b=200)
d = eval("a+b",dict1)
print(d)
eval 函数会将字符串当做语句来执行,因此会被注入安全隐患。比如:字符串中含有删除文件的语句。那就麻烦大了。因此,使用时候,要慎重!!!
函数嵌套(内部函数)
在函数内部定义的函数!
def f1():
print('f1 running...')
def f2():
print('f2 running...')
f2()
f1()
上面程序中,f2()就是定义在 f1 函数内部的函数。f2()的定义和调用都在 f1()函数内部。
什么情况需要使用内部函数
- 封装 - 数据隐藏外部无法访问“嵌套函数”。
- 贯彻 DRY(Don’tRepeatYourself) 原则嵌套函数,可以让我们在函数内部避免重复代码。
- 闭包
nonlocal关键字
nonlocal: 用来声明外层函数的局部变量。(在内层函数中使用)
global: 用来声明全局变量。
# 测试nonlocal、global关键字的用法
a = 10
def outer():
b = 10
def inner():
nonlocal b
print('inner: ', b)
b = 20
global a
a = 100
inner()
print('outer b: ', b)
outer()
print(a)
运行结果:
inner: 10
outer b: 20
100
LEGB 规则
Python 在查找“名称”时,是按照 LEGB 规则查找的:Local–>Enclosed–>Global–>Built in
- Local: 指的就是函数或者类的方法内部
- Enclosed:指的是嵌套函数(一个函数包裹另一个函数,闭包)
- Global: 指的是模块中的全局变量
- Built in: 指的是 Python 为自己保留的特殊名称。
如果都没找到就会报错。
#测试 LEGB
str = "global"
def outer():
str = "outer"
def inner():
str = "inner"
print(str)
inner()
outer()
依次将几个 str 注释掉,观察控制台打印的内容,体会 LEBG 的搜索顺序。