Python 装饰器

注意:这并不是一篇装饰器教程


@dec2
@dec1
def func(arg1, arg2, ...):
    pass

上面的代码等价于下面的代码:

def func(arg1, arg2, ...):
    pass
func = dec2(dec1(func))

装饰器会在和函数被解释的时候运行一次用于包装函数,运行以下代码将输出两次第四行定义的文本:

from functools import wraps

def code(fn):
    print("Decorator code")
    @wraps(fn)
    def w(*args,**kwargs):
        return fn(*args,**kwargs)
    return w

@code
def fun1(a,b):
    return a+b

@code
def fun2(a,b):
    return a-b

带参数的装饰器:

from functools import wraps

def code(name):
    print("Decorator code : %s" % name)
    def f(fn):
        @wraps(fn)
        def w(*args,**kwargs):
            return fn(*args,**kwargs)
        return w
    return f

@code("fun1")
def fun1(a,b):
    return a+b

@code("fun2")
def fun2(a,b):
    return a-b

示例:单例类的修饰器:

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    ...

python内置的装饰器

  1. @classmethod
class C:
    @classmethod
    def func(cls):
        pass
        
C.func()
  1. @property

这个装饰器可以创建只读属性

class Data:
    @property
    def property(self) -> int:
        return 200

    def method(self) -> int:
        return 100

c = Data()
print(c.property) # 可以通过调用属性的形式来调用方法,后不需要加()
print(c.method()) # 正常的方法调用
  1. @staticmethod
class C:
    @staticmethod
    def func(cls):
        pass
        
C.func()