详解python的修饰符
Python 中的修饰符(Decorator)是一种用于修改或扩展函数或类行为的工具。它们本质上是一个函数,接受另一个函数或类作为参数,并返回一个新的函数或类。修饰符通常用于在不修改原函数或类代码的情况下,添加额外的功能。
1. 基本概念
- 修饰符函数:一个接受函数或类作为参数,并返回新函数或类的函数。
- 语法糖:使用
@
符号简化修饰符的应用。
2. 函数修饰符
函数修饰符用于修改或扩展函数的行为。以下是一个简单的例子:
def my_decorator(func):
def wrapper():
print("Before function call")
func()
print("After function call")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
输出:
Before function call
Hello!
After function call
my_decorator
是一个修饰符函数,接受func
作为参数。wrapper
是一个内部函数,用于包裹原函数func
,并在调用前后添加额外操作。@my_decorator
是语法糖,等同于say_hello = my_decorator(say_hello)
。
3. 带参数的函数修饰符
修饰符也可以接受参数,此时需要再嵌套一层函数:
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello {name}")
greet("Alice")
输出:
Hello Alice
Hello Alice
Hello Alice
repeat
是一个带参数的修饰符函数,返回decorator
函数。decorator
接受func
作为参数,返回wrapper
函数。wrapper
包裹原函数func
,并根据num_times
参数重复调用。
4. 类修饰符
修饰符也可以用于类,修改或扩展类的行为:
def my_class_decorator(cls):
class Wrapper:
def __init__(self, *args, **kwargs):
self.wrapped = cls(*args, **kwargs)
def display(self):
print("Before method call")
self.wrapped.display()
print("After method call")
return Wrapper
@my_class_decorator
class MyClass:
def display(self):
print("Displaying MyClass")
obj = MyClass()
obj.display()
输出:
Before method call
Displaying MyClass
After method call
my_class_decorator
是一个类修饰符,接受cls
作为参数。Wrapper
是一个内部类,用于包裹原类cls
,并在方法调用前后添加额外操作。@my_class_decorator
是语法糖,等同于MyClass = my_class_decorator(MyClass)
。
5. 内置修饰符
Python 提供了一些内置修饰符,如 @staticmethod
、@classmethod
和 @property
:
@staticmethod
:将方法定义为静态方法,不接收self
或cls
参数。@classmethod
:将方法定义为类方法,第一个参数为cls
。@property
:将方法定义为属性,可以通过实例访问。
class MyClass:
@staticmethod
def static_method():
print("Static method")
@classmethod
def class_method(cls):
print(f"Class method of {cls}")
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
MyClass.static_method()
MyClass.class_method()
obj = MyClass()
obj.name = "Alice"
print(obj.name)
输出:
Static method
Class method of <class '__main__.MyClass'>
Alice
6. 修饰符的链式调用
多个修饰符可以链式调用,顺序从下往上执行:
def decorator1(func):
def wrapper():
print("Decorator 1")
func()
return wrapper
def decorator2(func):
def wrapper():
print("Decorator 2")
func()
return wrapper
@decorator1
@decorator2
def say_hello():
print("Hello!")
say_hello()
输出:
Decorator 1
Decorator 2
Hello!
- 先应用
decorator2
,再应用decorator1
。
总结
Python 的修饰符是一种强大的工具,能够在不修改原函数或类代码的情况下,添加额外功能。它们广泛应用于日志记录、权限检查、性能测试等场景。理解修饰符的工作原理有助于编写更简洁、灵活的代码。