Python函数高级(命名空间、作用域、装饰器)
命名空间
在Python中每个函数、类、模块都有自己的命名空间,这个空间负责保存这个东西创建的变量名和对应的对象。当Python解释器执行某个函数或者类时,会自动创建一个与函数或类相对应的命名空间。
局部命名空间
在函数内部声明的变量,只在函数内部有效,也就是说,在函数外部是访问不到的。
def f():
a = 1
print(a) # 1
f()
print(a) # NameError: name 'a' is not defined
类似地,因为Python函数是可以嵌套的,所以每个内部函数也会创建一个属于自己的命名空间。
全局命名空间
当Python程序运行时,会自动创建一个全局命名空间(也可以称为模块命名空间),这个空间的生命期和整个程序是一致的,其中的变量在整个程序中都可以进行访问。
在模块中声明的函数、类、变量都属于全局命名空间,这些变量的作用域在整个模块中都是有效的。
a = 1
def f():
print(a)
f() # 1
内置命名空间
Python解释器自动创建的命名空间,其中存放了Python内置的函数和变量。这些名称在Python程序中无须声明即可直接使用。
作用域
Python中的作用域也是和命名空间紧密相关的,简单来说,作用域定义了一个名称(变量名、函数名、类名)在程序的哪个地方可以被访问到。
Python中有L(Local)、E(Enclosing)、G(Global)、B(Built-in)4种作用域。
L作用域
L作用域又称局部作用域,表示在当前函数内部定义的函数或变量,只在函数的局部范围内有效;在函数外部是无法访问的。
def f():
x = 'Hello, Python!'
def g():
print(x)
g()
f() # Hello, Python!
在上面的代码中,g
函数就是在f
内部定义的函数,它所在的作用域是L
,g
函数可以访问到外部的变量x
,因为x
在f
函数内部定义了,是属于f
函数的局部变量。
E作用域
E作用域又称封闭作用域,表示在一个嵌套函数中访问到外层函数的变量,只要嵌套的关系成立,就能够访问到外层函数中的变量。
def f():
x = 'Hello, Python!'
def g():
print(x)
return g
h = f()
h() # Hello, Python!
上面代码中,g
函数嵌套在f
函数内部,因此在g
函数中可以访问到f
函数内部的变量x
。注意,在这个示例中,f
函数返回的是g
函数,所以h
就是g
函数,调用h
实际上是调用g
函数。
G作用域
G作用域表示全局作用域,其中的变量是在整个程序中都有用的。
x = 123
def f():
print(x)
f() # 123
B作用域
B作用域表示内置作用域,其中的变量是Python语言自带的,可以直接使用。
例如:
print(123)
这里print
函数就是内置函数,在Python程序中可以直接使用。
装饰器
装饰器是Python语言中非常常见的一个特性,它可以动态地修改一个函数或类的行为,而不需要对函数或类本身进行修改。
定义装饰器
可以通过定义一个函数,这个函数会接收一个函数作为参数并返回一个函数。这个函数就是装饰器的定义。
例如:
def my_decorator(func):
def wrapper():
print('Before the function is called.')
func()
print('After the function is called.')
return wrapper
上面的代码定义了一个名为my_decorator
的装饰器函数,这个函数接收一个函数作为参数,在内部定义一个名为wrapper
的函数,wrapper
这个函数就是执行实际函数前后需要附加行为的地方。在完成wrapper
函数的定义后,将其作为结果返回。
使用装饰器
定义了一个装饰器之后,可以通过在函数定义时应用这个装饰器来改变原有函数的行为。
例如:
@my_decorator
def say_hello():
print('Hello, World!')
@my_decorator
语句表明现在要对say_hello
函数进行装饰,将my_decorator
这个装饰器应用在say_hello
上面。
多个装饰器的应用
可以对一个函数应用多个装饰器。
例如:
def my_decorator1(func):
def wrapper():
print('Before the function is called by decorator1.')
func()
print('After the function is called by decorator1.')
return wrapper
def my_decorator2(func):
def wrapper():
print('Before the function is called by decorator2.')
func()
print('After the function is called by decorator2.')
return wrapper
@my_decorator1
@my_decorator2
def say_hello():
print('Hello, World!')
在这个示例中,say_hello
函数先被my_decorator2
装饰器装饰,然后再被my_decorator1
装饰器装饰。这意味着my_decorator1
的wrapper
函数将实际被传递到my_decorator2
的wrapper
函数中。这样一来,在调用say_hello
函数时,首先会执行my_decorator2
的wrapper
函数,然后执行my_decorator1
的wrapper
函数,最后才执行实际函数。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python函数高级(命名空间、作用域、装饰器) - Python技术站