在Python中,你可以使用@
符号来定义一个注解,也称为装饰器(decorator)。
定义一个注解的基本语法如下:
def my_decorator(func):
def wrapper():
print("Before function is called.")
func()
print("After function is called.")
return wrapper
@my_decorator
def my_function():
print("Function is called.")
my_function()
在上面的示例中,我们定义了一个名为my_decorator
的函数,它接受一个函数作为参数,并返回一个内部函数wrapper
。在wrapper
函数中,我们首先打印一条消息,然后调用传入的函数func
,最后再打印一条消息。这样就形成了一个函数装饰器。
接下来,在my_function
函数上方使用@my_decorator
注解,将my_decorator
函数应用到my_function
函数上。当我们调用my_function
函数时,实际上是调用了被my_decorator
装饰过的函数。
注解可以带有参数,例如:
def repeat(num):
def my_decorator(func):
def wrapper(*args, **kwargs):
for i in range(num):
func(*args, **kwargs)
return wrapper
return my_decorator
@repeat(3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
在上面的示例中,我们定义了一个名为repeat
的函数,它接受一个整数作为参数,并返回一个装饰器函数my_decorator
。在my_decorator
函数中,我们定义了一个内部函数wrapper
,它接受任意参数,并将被装饰的函数调用多次。最后,我们返回wrapper
函数,以完成装饰器的定义。
接下来,在say_hello
函数上方使用@repeat(3)
注解,将repeat
函数应用到say_hello
函数上。当我们调用say_hello("Alice")
函数时,实际上是调用了被repeat
装饰过的函数,它会输出三遍"Hello, Alice!"。
需要注意的是,装饰器可以带有不同数量的层级。也就是说,你可以使用一个或多个装饰器来修饰同一个函数。在这种情况下,函数会按照从外到内的顺序依次应用所有装饰器。例如:
def my_decorator1(func):
def wrapper():
print("Decorator 1")
func()
return wrapper
def my_decorator2(func):
def wrapper():
print("Decorator 2")
func()
return wrapper
@my_decorator1
@my_decorator2
def my_function():
print("Function is called.")
my_function()
在上面的示例中,我们定义了两个装饰器函数my_decorator1
和my_decorator2
,并将它们都应用到my_function
函数上。当我们调用my_function
函数时,实际上是依次调用了被my_decorator1
和my_decorator2
装饰过的函数,输出结果为:
Decorator 1
Decorator 2
Function is called.
我们可以使用注解来修饰类,同样也可以使用装饰器来实现。
下面是一个使用装饰器来修饰类的示例:
def my_decorator(cls):
class MyDecoratedClass(cls):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.decorator_property = "Decorator Property"
def decorated_method(self):
print("Decorator Method")
super().decorated_method()
return MyDecoratedClass
@my_decorator
class MyClass:
def __init__(self, name):
self.name = name
def decorated_method(self):
print(f"Hello, {self.name}!")
my_object = MyClass("Alice")
my_object.decorated_method()
print(my_object.decorator_property)
在上面的示例中,我们定义了一个名为my_decorator
的装饰器函数,它接受一个类作为参数,并返回一个新的被装饰过的类。在MyDecoratedClass
类中,我们重写了__init__
方法,在初始化对象时添加了一个名为decorator_property
的属性。同时,我们还重写了decorated_method
方法,在调用父类的方法之前输出一条消息。
接下来,在MyClass
类上方使用@my_decorator
注解,将my_decorator
函数应用到MyClass
类上。当我们创建MyClass
类的实例时,实际上是创建了被my_decorator
装饰过的类的实例,并且该实例具有decorator_property
属性和decorated_method
方法的新行为。
需要注意的是,类装饰器也可以带有不同数量的层级。也就是说,你可以使用一个或多个装饰器来修饰同一个类。在这种情况下,类会按照从外到内的顺序依次应用所有装饰器。
注解装饰类的应用场景相对较少,但在某些情况下可能会很有用,例如添加额外的属性或方法,或者修改现有的属性或方法的行为。