高阶函数
高阶函数:函数名可以作为参数传递输入,函数名还可以作为返回值返回
函数名可以重新赋值,因为其本身就是一个变量
函数本身就是一个对象,
函数的变量名f本身就是指向函数本身的,加上括号后f()就可以执行其内容了
函数的变量名还可以作为函数参数,也可以作为函数的返回值
def add(x, y, f): return f(x) + f(y) res = add(3, -6, abs) print(res) # 9 ############################################################ def f(n): return pow(n, n) def foo(a, b, fun): return fun(a) + fun(b) def hello(): print('hello world') # 函数名可以重新赋值,因为其本身就是一个变量 hhh = foo # 函数名可以作为参数去执行 v = foo(2, 3, f) print(v) good = hhh(2, 3, f) print(good)
函数返回值
要想获取函数的执行结果,就可以用return语句把结果返回
注意:
1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,也可以理解为 return 语句代表着函数的结束
2. 如果未在函数中指定return,那这个函数的返回值为None
3. return多个对象,Python会把这多个对象组装成一个元组作为一个一个整体【元组】结果输出。
return 1,2,3,'name' ==> (1,2,3,'name')
函数作用域
python中的作用域分4种情况:
L:local,局部作用域,即函数中定义的变量;
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
G:globa,全局变量,就是模块级别定义的变量;
B:built-in,系统固定模块里面的变量,比如int, bytearray等。
搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。
当然,local和enclosing是相对的,enclosing变量相对上层来说也是local。
x = int(2.9) # int built-in g_count = 0 # global def outer(): o_count = 1 # enclosing def inner(): i_count = 2 # local print(o_count) # print(i_count) 找不到 inner() outer() # print(o_count) #找不到
作用域产生
在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的
变量修改
局部变量修改全局变量: global和nolocal 关键字修改
global关键字;
当修改的变量是在全局作用域(global作用域)上的[global不能嵌套作用域上],就要使用global先声明一下
count = 10 def outer(): # global count = 90 SyntaxError: invalid syntax 语法错误 global count # 局部变量想要修改全局变量,必须声明变量为global print(count) count = 5 # 局部变量想要修改全局变量,必须声明变量为global print(count) outer()
nolocal关键字;
修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量
def outer(): count = 10 def inner(): nonlocal count # 使用nolocal声明后,就可以修改外部的count变量了 count = 20 print(count) inner() print(count) outer() #20 #20
作用域小结 :
(1)变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;
(2)只有模块、类、及函数才能引入新作用域;
(3)对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
(4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个 关键字,就能完美的实现闭包了。