Python装饰器访问错误的函数

时间:2017-01-21 15:08:29

标签: python python-3.x python-decorators

我的理解:

根据我对装饰器的理解,以下代码

def myDecorator(func):
   ...

@myDecorator
def myFunc()

相当于

myFunc = myDecorator(myFunc)

我的实验

所以我用以下代码来玩这个概念

def myDecorator(func):
        func()

@myDecorator
def myFunc():
    print("MyFunc is run")

@myDecorator
def myFunc2():
    print("MyFunc2 is run")

myFunc

输出

MyFunc is run
MyFunc2 is run

我的问题

会发生什么?为什么要打印MyFunc2 is run行? Aren&#t; t myFunc相当于myFunc = myDecorator(myFunc)?如果是这种情况,为什么运行myFunc2语句?

2 个答案:

答案 0 :(得分:1)

您正在将函数对象传递给myDecorator()函数。该函数接收函数对象作为func参数。然后,您使用func() 调用该函数。

你是正确的,函数对象上的@myDecorator会导致调用该装饰器,并传入函数对象。但是当发生这种情况时,你似乎对感到困惑。它发生在Python执行def语句的那一刻:

>>> def myDecorator(func):
...     func()
...
>>> @myDecorator
... def foo():
...     print('The foo() function is called')
...
The foo() function is called

请注意,由于myDecorator()没有return语句,foo现已绑定到None

>>> foo is None
True

您的最后一行myFunc只是引用了None对象。你没有调用它,所以 表达式不会导致任何打印。 无法调用它,因为None不可调用。

答案 1 :(得分:0)

为了完整性 - 一个"泛型"正确的装饰器返回一个新的函数对象,然后taht替换声明它的范围内的原始函数:

def myDecorator(func):
    def wrapper(*args, **kwargs):
        """Calls original function with whatever parameters 
        and returns its return value.
        """
        print("Running decorator code")
        return func(*ars, **kwargs)
    # Returns the newly created 'wrapper' function
    # that will replace the original "func"
    return wrapper

@myDecorator
def myFunc():
    print("MyFunc is run")

@myDecorator
def myFunc2():
    print("MyFunc2 is run")

myFunc()