Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 类方法中的装饰器:与';getattr';_Python_Oop_Metaprogramming_Decorator_Python Decorators - Fatal编程技术网

Python 类方法中的装饰器:与';getattr';

Python 类方法中的装饰器:与';getattr';,python,oop,metaprogramming,decorator,python-decorators,Python,Oop,Metaprogramming,Decorator,Python Decorators,我需要为类方法制作包装,在调用特定方法之前和/或之后执行 下面是一个简单的例子: class MyClass: def call(self, name): print "Executing function:", name getattr(self, name)() def my_decorator(some_function): def wrapper(): print("Before we call

我需要为类方法制作包装,在调用特定方法之前和/或之后执行

下面是一个简单的例子:

class MyClass:

    def call(self, name):
        print "Executing function:", name
        getattr(self, name)()

    def my_decorator(some_function):
        def wrapper():
            print("Before we call the function.")
            some_function()
            print("After we call the function.")
            return wrapper

    @my_decorator
    def my_function(self):
        print "My function is called here."


engine = MyClass()
engine.call('my_function')
这在
getattr(self,name)(
行中给出了一个错误:

TypeError:“非类型”对象不可调用

如果我在类方法之前注释掉decorator,那么它可以完美地工作:

class MyClass:

    def call(self, name):
        print "Executing function:", name
        getattr(self, name)()

    def my_decorator(some_function):
        def wrapper():
            print("Before we call the function.")
            some_function()
            print("After we call the function.")
            return wrapper

    # @my_decorator
    def my_function(self):
        print "My function is called here."


engine = MyClass()
engine.call('my_function')
输出为:

执行函数:my_函数

我的函数在这里调用

装饰器本身与教科书中的示例相同。在Python中使用
getattr
调用修饰的方法时,似乎在较低级别出现了问题


您对如何修复此代码有什么想法吗?

这与
getattr()
无关。当您尝试直接调用
my_function()
时,会出现完全相同的错误:

>>> engine.my_function()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
  • 包装器不接受任何参数,包括
    self
    。一旦你正确归还了它,你就需要它来工作

  • 第一个问题通过取消
    返回包装
    行的缩进来解决;它当前是
    包装器
    函数本身的一部分,应该是
    我的装饰器
    的一部分:

    def my_decorator(some_function):
        def wrapper(self):
            print("Before we call the function.")
            # some_function is no longer bound, so pass in `self` explicitly
            some_function(self)
            print("After we call the function.")
        # return the replacement function
        return wrapper
    

    这与
    getattr()
    无关。当您尝试直接调用
    my_function()
    时,会出现完全相同的错误:

    >>> engine.my_function()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'NoneType' object is not callable
    
  • 包装器不接受任何参数,包括
    self
    。一旦你正确归还了它,你就需要它来工作

  • 第一个问题通过取消
    返回包装
    行的缩进来解决;它当前是
    包装器
    函数本身的一部分,应该是
    我的装饰器
    的一部分:

    def my_decorator(some_function):
        def wrapper(self):
            print("Before we call the function.")
            # some_function is no longer bound, so pass in `self` explicitly
            some_function(self)
            print("After we call the function.")
        # return the replacement function
        return wrapper
    

    你的问题只得到了部分回答。下面介绍如何修改
    包装器
    (以及
    调用()
    )方法,以便它们接受其他参数,从而使其完全工作(以及在Python 2和3中):

    输出:

    执行函数:“我的函数”
    在调用函数之前。
    我的函数在这里调用。
    在我们调用函数之后。
    
    您的问题只得到了部分回答。下面介绍如何修改
    包装器
    (以及
    调用()
    )方法,以便它们接受其他参数,从而使其完全工作(以及在Python 2和3中):

    输出:

    执行函数:“我的函数”
    在调用函数之前。
    我的函数在这里调用。
    在我们调用函数之后。