目录
目录
lambda表达式和匿名函数
lambda
表达式可以用来声明匿名函数。lambda
函数是一种简单的、在同一行中定义函数的方法。lambda
函数实际生成了一个函数对象。
lambda
表达式只允许包含一个表达式,不能包含复杂语句,该表达式的计算结果就是函数的返回值。
lambda
表达式的基本语法如下:
lambda arg1,arg2,arg3... : <表达式>(arg1
arg2
arg3
为函数的参数。<表达式>相当于函数体。运算结果是:表达式的运算结果。)
lambda表达式使用:
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))
执行结果:
<function <lambda> at 0x0000000002BB8620>
9
12 21 32
eval()函数的用法和注入安全隐患问题
功能:将字符串str
当成有效的表达式来求值并返回计算结果。
语法: 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函数
会将字符串当做语句来执行,因此会被注入安全隐患。比如:字符串中含有删除文件的语句。那就麻烦大了。因此,使用时候,要慎重!!!}
递归函数_函数调用内存分析_栈帧的创建
-
递归(recursion)是一种常见的算法思路,在很多算法中都会用到。比如:深度优先搜索(DFS:Depth First Search)等。
-
递归的基本思想就是“自己调用自己”
递归函数指的是:自己调用自己的函数,在函数体内部直接或间接的自己调用自己。每个递归函数必须包含两个部分:
-
终止条件
表示递归什么时候结束。一般用于返回值,不再调用自己。
-
递归步骤
把第n步的值和第n-1步相关联。
⚠️递归函数由于会创建大量的函数对象、过量的消耗内存和运算能力。在处理大量数据时,谨慎使用。
如下是一个简单的递归程序:
def my_recursion(n):
print("start:" + str(n))
if n == 1:
print("recursion over!")
else:
my_recursion(n - 1)
print("end:" + str(n))
my_recursion(3)
运算结果:
start:3 start:2 start:1 recursion over! end:1 end:2 end:3
使用递归函数计算阶乘(factorial)
def factorial(n):
if n==1:
return 1
return n*factorial(n-1)
print(factorial(5))
嵌套函数_内部函数_数据隐藏
嵌套函数:在函数内部定义的函数!
def outer():
print('outer running...')
def inner():
print('inner running...')
inner()
outer()
执行结果:
outer running...
inner running...
上面程序中,inner()
就是定义在outer()
函数内部的函数。inner()
的定义和调用都在outer()
函数内部。
一般在什么情况下使用嵌套函数?
-
封装 - 数据隐藏
外部无法访问“嵌套函数”。
-
贯彻 DRY(Don’t Repeat Yourself) 原则
-
嵌套函数,可以让我们在函数内部避免重复代码。
-
闭包
使用嵌套函数避免重复代码
def printChineseName(name,familyName):
print("{0} {1}".format(familyName,name))
def printEnglishName(name,familyName):
print("{0} {1}".format(name, familyName))
使用1个函数代替上面的两个函数
def printName(isChinese,name,familyName):
def inner_print(a,b):
print("{0} {1}".format(a,b))
if isChinese:
inner_print(familyName,name)
else:
inner_print(name,familyName)
printName(True,"小七","温")
printName(False,"George","Bush")
nonlocal和global关键字
nonlocal
用来在内部函数中,声明外层的局部变量。
global
函数内声明全局变量,然后才使用全局变量
使用nonlocal声明外层局部变量
#测试nonlocal、global关键字的用法
a = 100
def outer():
b = 10
def inner():
nonlocal b #声明外部函数的局部变量
print("inner b:",b)
b = 20
global a #声明全局变量
a = 1000
inner()
print("outer b:",b)
outer()
print("a:",a)
LEGB规则
Python在查找“名称”时,是按照LEGB规则查找的:
Local
指的就是函数或者类的方法内部
Enclosed
指的是嵌套函数(一个函数包裹另一个函数,闭包)
Global
指的是模块中的全局变量
Built in
指的是Python为自己保留的特殊名称
如果某个
name
映射在局部local
命名空间中没有找到,接下来就会在闭包作用域enclosed
进行搜索,如果闭包作用域也没有找到,Python就会到全局global
命名空间中进行查找,最后会在内建built-in
命名空间搜索 (如果一个名称在所有命名空间中都没有找到,就会产生一个NameError
)
#测试LEGB
s = "global"
def outer():
s = "outer"
def inner():
s = "inner"
print(s)
inner()
outer()
我们依次将几个s
注释掉,观察控制台打印的内容,体会LEBG的搜索顺序。