这是我参与11月更文挑战的11天,活动详情查看:2021最后一次更文挑战。
函数作用域
Python
中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
Python
的作用域一共有4种,分别是:
L(local)
:局部作用域,即函数中定义的变量;E(enclosing)
:嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;G(global)
:全局变量,就是模块级别定义的变量;B(build-in)
:内建作用域,系统固定模块里面的变量,比如:int()
等。
函数作用域优先级:
# 局部作用域(L)>父级函数作用域(E)>全局作用域(G)>系统模块(B)
a = int(3.14) # built-in
b = 11 # global
def outer():
c = 5 # enclosing
def inner():
d = 6 # local
return 1
⚠️注意:在函数内部无法直接修改全局变量。
count = 10
def test():
count = 5
print(count)
test() # 5
print(count) # 10
global
关键字
那当我们需要在函数内部直接修改全局变量时,我们可以将函数内部的局部变量通过global
关键字声明为全局变量:
count = 10
def test():
global count
count = 5
print(count)
test() # 5
print(count) # 5
匿名函数
当我们在传入函数时,有些时候,不需要去重复调用该函数,直接传入匿名函数更方便,也无需担心函数名冲突,并且还可以将匿名函数赋值给一个变量,再利用变量来调用该函数。匿名函数的表达式为:
lambda x:x*x
- 关键字
lambda
表示匿名函数; - 冒号前面的x表示函数参数;
x*x
是匿名函数的表达式,并且注意匿名函数只能有一个表达式,不用写return
,返回值就是该表达式的结果。实际上就是:
def f(x):
return x*x
匿名函数作返回值:
def fx(i,j):
return lambda :i*j
f = fx(6,6)
print(f())
匿名函数作实参:
def test(a,b,func):
res = func(a,b)
return res
nums = test(11,22,lambda x,y:x+y)
print(nums)
高阶函数
实际上,我们学习过的map()
,filter()
等都是高阶函数。那么只要满足以下一个条件的就是高阶函数:
- 函数名作为参数传入
- 函数名作为返回值
闭包
闭包的定义需要满足以下三个条件:
- 在一个外函数中定义了一个内函数;
- 内函数里运用了外函数的临时变量;
- 并且外函数的返回值是内函数的引用。
def test(number):
print("--1--")
def test_in(number_in): # 1.内部函数
print(number_in)
print("--2--")
return number_in + number # 2.外部环境的变量引用
print("--3--")
return test_in #3.内部函数test_in返回
res = test(20) # res = test_in
res(25)
装饰器
由于我们在开发中要遵守封闭开放原则,所以python
开发者开始使用装饰器:
- 在不改变源代码的情况下为函数添加新的功能。并且使用
@
符号,@
符号为语法糖:
import time
def calcu_time(func):
def test_in():
start = time.time()
func()
end = time.time()
print("spend {}".format(end - start))
return test_in
@calcu_time
def test1():
print("---test1---")
time.sleep(2)
test1()