Python 類裝飾器解析


1. 類裝飾器(都不帶參數)

class ClassDeco:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print(f'Running {self.func.__name__}')
        self.func()
        print(f'End {self.func.__name__}')

@ClassDeco  # 等價於 foo = ClassDeco(foo)
def foo():
    print('do something')

# call foo()
# OUT:
#     Running foo
#     do something
#     End foo

2. 類裝飾器帶參數

class ClassDeco:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __call__(self, func, *args, **kwargs):
        print(f'Running {func.__name__}')
        print(f'Using x + y = {self.x + self.y}')
        return func


@ClassDeco(1, 2) # 等價於 foo = ClassDeco(1, 2)(foo)
def foo():
    print('do something')


# call foo()
# OUT:
#     Running bar1
#     Using x + y = 3
#     do something

3. 類裝飾器不帶參數,被包裝對象帶參數

class ClassDeco:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print(f'Running {self.func.__name__}')
        self.func(*args, **kwargs)
        print(f'End {self.func.__name__}')

@ClassDeco  # 等價於foo = ClassDeco(foo)
def foo(a, b):
    print('do something')
    print(f'return a + b = {a + b}')


# foo(1, 2)
# OUT:
#     Running foo
#     do something
#     return a + b = 3
#     End foo

4. 類裝飾器帶參數且被裝飾對象也帶參數

from functools import wraps

class ClassDeco:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __call__(self, func, *args, **kwargs):
        print(f'Using x + y = {self.x + self.y}')
        @wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)
            print(f'Ending {func.__name__}')
        return wrapper


@ClassDeco(1, 2) # 等價於 foo = ClassDeco(1, 2)(foo)
def foo(a, b):
    print('do something')
    print(f'return a + b = {a + b}')


# call foo(3, 4)
# OUT:
#     Using x + y = 3
#     do something
#     return a + b = 7
#     Ending foo

if __name__ == '__main__':
    foo(3, 4)

5. 參考

理解Python類裝飾器__call__


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM