作用域
程序创建, 访问, 改变一个变量时, 都是在一个保存该变量的空间内进行, 这个空间被称为命名空间, 即作用域
Built-in
内置- 可以在Python环境中的任何模块, 任意位置访问和调用
Global
全局变量- 只作用于当前模块(可以理解为当前文件)
- 可以简单地理解为定以在函数外的变量就是全局变量, 如果在函数体定义那就时局部变量.
如何将局部变量变成全局变量?
使用
global
关键字a = 1 def foo(): global a a = 2 print(a) foo() print(a)
Enclosed(嵌套)
自由变量在嵌套函数中, 访问函数体之外的非全局变量
- 只作用于嵌套函数体
- 最大的应用就是闭包
- 自由变量是个相对的概念
将局部变量变成自由变量
使用
nonlocal
关键字def make_averager(): total = 0 count = 0 def averager(value): nonlocal total, count total += value count += 1 return total / count return averager my_avg = make_averager() print(my_avg(1)) print(my_avg(2))
Local
局部变量- 只作用于当前函数体
一旦变量在函数体中赋值, 那么该变量相对该函数来说就是局部变量
a = 1 b = [] def foo(): a = 2 b.append(2) # 局部变量会在函数声明的时候就定义好 # 不是按照我们逻辑思维上先执行全局变量b.append(2), 然后再声明一个局部变量b # 而是再函数声明之初就已经定义了b为局部变量 # b = 3 return None foo() print(a) print(b)
闭包和装饰器
闭包
闭包指延申了作用域的函数, 也就是作用域中的
Enclosed
的概念def make_averager(): series = [] def averager(value): series.append(value) total = sum(series) return total / len(series) return averager # my_avg就是延申了作用域的函数 # series就是被延申作用域的变量 my_avg = make_averager() print(my_avg(1)) print(my_avg(2))
装饰器
实现原理
就是闭包, 延申了被装饰函数的作用域, 本质是将函数作为参数传递给一个可调用对象(函数或类)
目的
增加和扩展可调用对象(函数或类)的行为
实现一个装饰器
通过
@
关键字装饰函数def clock_it_deco(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"{func.__name__} execute time: {format(end_time - start_time, '.2f')} s") return result return wrapper # @other_deco @clock_it_deco def foo(a, b): count = 1 while True: if count > a ** b: break count += 1 foo(10, 5)
等同于
foo = clock_it_deco(foo) foo(10, 5)
Comment here is closed