Python中装饰器的内部机制是怎样的

问题描述 投票:0回答:2

我知道装饰器是一个函数,它接受另一个函数并扩展其行为。 在下面的示例中,我之前假设 test() 现在实际上等同于 decorator(test)()

def decorator(func):
    def wrapper(*args, **kwargs):
        ...
        res = func(*args, **kwargs)
        ...
        return res
    return wrapper

@decorator
def test():
    pass

但是,在装饰器中添加函数属性后,同时运行test()decorator(test)(),结果是不同的。看起来,在 decorator(test)() 的情况下,装饰器函数确实运行了,因此 num 被重置;当使用 @decorator 时,装饰器函数没有按照我的预期运行?

def decorator(func):
    decorator.num = 0
    def wrapper(*args, **kwargs):
        ...
        res = func(*args, **kwargs)
        ...
        return res
    return wrapper

@decorator
def test():
    pass
   
def test2():
    pass

decorator.num = 5
test()
print(decorator.num)

decorator.num = 5
decorator(test2)()
print(decorator.num)

---------------------
5
0

python decorator
2个回答
3
投票

您的困惑源于何时装饰器运行。语法

@decorator
def foo(): ...

相当于

def foo(): ...

foo = decorator(foo)

也就是说,在函数定义之后,立即调用装饰器,并且调用装饰器的结果被赋值回原来的函数名。它仅在定义时调用一次,而不是每个函数调用一次。

班级也是如此。语法

@decorator
class Foo: ...

相当于

class Foo: ...

Foo = decorator(Foo)

0
投票

先生。 Mayolo,一个与装饰器语法相关的问题:

如果语法

@decorator
class Foo: ...

相当于

class Foo: ...

Foo = decorator(Foo)

以下示例使用装饰器@property:

class A:

    def __init__(self, name):

        self._name = name


    @property
    def name(self):
        
        print('Returning value')
        
        return self._name
    
    @name.setter
    def name(self, value):
        
        print('Setting value')
        
        self._name = value

可以重写为:

class A:

    def __init__(self, name):

        self._name = name


    def name(self):
        
        print('Returning value')
        
        return self._name
    
    name = property(name)
    
    def name(self, value):                      # Overrides the above identifier 'name'
        
        print('Setting value')
        
        self._name = value

    name = name.setter(name)

这会产生错误,因为第二个方法“name”覆盖了标识符“name”。你能解释一下装饰器@property是如何实现的吗?非常感谢您的回复。

© www.soinside.com 2019 - 2024. All rights reserved.