python高阶(六)——函数学习
全局变量和局部变量
局部变量:定义在函数内部的变量称为局部变量(函数的形参也是局部变量)
局部变量只能在函数内部使用 局部变量在函数调用时才能够被创建,在函数调用之后会自动销毁
全局变量:定义在函数外部,模块内部的变量称为全局变量
全局变量,所有的函数都可以直接访问(但函数内部不能将其直接赋值)
a = 100 b = 200 def fx(c): d = 400 print(a, b, c, d) fx(300) print('a =', a) print('b =', b) # print('c =', c) # 出错,不能访问局部变量 # print('d =', d) def fy(c): d = 40 a = 10 # 此时会创建局部变量a,不会修改全局变量a print(a, b, c, d) print("-------------------") fy(30) print('a =', a)
局部变量说明:
1. 在函数内首次对变量赋值是创建局部变量,再次为变量赋值是修改局部变量的绑定关系
2. 在函数内部的赋值语句不会对全局变量造成影响
3. 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个模块范围内访问
globals 和 locals 函数
globals(): 返回当前全局作用域内变量的字典
locals(): 返回当前局部作用域内为量的字典
a = 1 b = 2 c = 3 def f1(c, d): e = 300 print("locals()返回: ", locals()) print('globals()返回', globals())
f1(100, 200)
#locals()返回: {'e': 300, 'd': 200, 'c': 100} #globals()返回 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002155B5DB208>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/PycharmProjects/Data_analysis/Day02/test.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'f1': <function f1 at 0x000002155B8469D8>}
函数变量:函数名是变量,它在创建函数时绑定一个函数
def f1(): print("f1被调用") fx = f1 fx() # 等同于 f1()
一个函数可以作为另一个函数的参数传递
# 看懂下面的函数在做什么: def fx(a, fn): return fn(a) L = [5, 9, 4, 6] print('最大值是:', fx(L, max)) print('最小值是:', fx(L, min)) print('和是:', fx(L, sum))
函数可以返回另一个函数(即:另一个函数可以返回一个函数)
# 此示例示意函数为作函数的返回值 def get_fx(): s = input('请输入您要做的操作: ') if s == '求最大': return max elif s == '求最小': return min elif s == '求和': return sum L = [2,4,6,8,10] print(L) f1 = get_fx() print(f1(L))
函数嵌套定义:函数的嵌套定义是指一个函数里用def语句来创建其它的函数
def fn_outer(): print("fn_outer被调用!") def fn_inner(): print("fn_inner被调用") fn_inner() fn_inner() print('fn_outter调用结束') fn_outer()
#fn_outer被调用! #fn_inner被调用 #fn_inner被调用 #fn_outter调用结束
python 作用域:作用域也叫名字空间,是访问变量时,查找变量名的范围空间
python的四个作用域 LEGB
局部作用域 (Local function) L
外部嵌套函数作用域 (Enclosing Function Locals) E
函数定义所在模块(文件)的作用域 (Global(Mudule)) G
python 内置模块的作用域 (Builtin(python)) B
# 此示例说明python的作用域 v = 100 # 全局作用域 def fun1(): v = 200 # 外部嵌套函数的作用域 print('fun1内的v=', v) def fun2(): v = 300 # 局部作用域 print("fun2内的v=", v) fun2() fun1() print("v =", v)
变量名的查找规则:L --> E --> G --> B
在默认情况下,对变量名赋值会创建或改变本作用域内的变量
global语句
作用:
1.告诉解释器, global语句声明的一个或多个变量,这些变量的作用域为模块级的作用域,也称作全局变量
2.全局声明(global)将赋值变量映射到模块文内部的作用域
语法:global 变量1, 变量2, ...
v = 100 def fn(): global v v = 200 fn() print(v) # 200
- 全局变量如果要在函数内部被赋值,则必须经过全局声明(否则会被认为是局部变量)
- 全局变量在函数内部不经过声明就可以直接访问
- 不能先声明局部的变量,再用global声明为全局变量,此做法不附合规则
- global 变量列表里的变量不能出现在此作用域内的形参列表里
nonlocal 语句
作用:告诉解释器, nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量
语法: nonlocal 变量名1, 变量名2, ...
# 此示例示意nonlocal语句的用法: var = 100 def f1(): var = 200 print("f1里的var=", var) def f2(): nonlocal var var = 300 # 此处要想修改f1里的var变量怎么办? print("f2里的var=", var) f2() print("f2调用结束后f1里的var值为", var) f1() print('全局的var =', var)
- nonlocal语句只能在被嵌套函数内部进行使用
- 访问nonlocal变量将对外部嵌套函数的作用域的变量进行操作
- 当有两层或两层以上的函数嵌套时,访问nonlocal变量只对最近一层的变量进行操作
- nonlocal语句的变量列表里的变量名,不能出现在此函数的参数列表中
lambda 表达式(又称匿名函数)
作用:”创建一个匿名函数对象 同 def 类似,但不提供函数名
语法:lambda [参数1, 参数2, ...]: 表达式 [] 里的内容可以省略
def myadd(x, y): return x + y # 以上函数可以改写为: myadd = lambda x, y: x + y print('2 + 3 =', myadd(2, 3))
- lambda 只是一个表达式,它用来创建一个函数对象
- 当lambda表达式调用时,先执行冒号后(:)的表达式,并返回表达式的结果的引用
- lambda 表达式创建的函数只能包含一条"表达式"
- lambda 比函数简单,且可以随时创建和销毁,有利于减少程序的偶合度
eval() 和 exec()函数
eval() 函数
作用:把一个字符串当成一个表达式来执行,返回表达式执行后的结果
格式:eval(source, global=None, locals=None)
x = 100 y = 200 a = eval('x+y') print(a)
exec() 函数
作用:把一个字符串当成程序来执行
格式:exec(source, globals=None, locals=None)
x = 100 y = 200 s = 'z = x+y; print(z); del z; print("删除成功"' exec(s) # 执行s绑定的语句
eval 和 exec的两个参数globals 和 locals:此两个参数是用来设置'表达式'或'程序'运行的全局变量和局部变量
x = 100 y = 200 s = 'print(x, y, x + y)' exec(s) # 100 200, 300 exec(s, {'x': 10, 'y': 20}) # 10, 20, 30 exec(s, {'x': 10}, {'x': 1, 'y': 2}) # 1 2 3 exec(s, {'x': 10}, {'y': 2}) # 10 2 12