【问题标题】:decorate method after declaration声明后装饰方法
【发布时间】:2026-02-03 00:15:02
【问题描述】:

我有一个库中的类,比如说 MyClass 和一个方法 my_method

from MyLibrary import MyClass
obj = MyClass()
result = obj.my_method('arg')

我不知道最初的实现,但我想装饰my_method,特别是我想检查返回值是否为not None,以防引发异常,如:

result = obj.my_method('arg')
if result is None: raise ValueError()

这很无聊,因为我需要做很多次。特别是当我调用obj.my_method('arg') 时,我不想更改代码。我正在尝试:

def safe_method(self, *args):
  result = self.my_method(*args)
  if result is None: raise ValueError()
  return result

MyClass.my_method = safe_method

这不起作用:

RuntimeError: maximum recursion depth exceeded while calling a Python object

我明白为什么,但我无法解决问题

【问题讨论】:

    标签: python python-decorators


    【解决方案1】:

    你可以这样装饰它:

    def safe_decorator(func):
        def wrapper(self, *args):
            result = func(self, *args)
            if result is None:
                raise ValueError()
            return result
        return wrapper
    
    MyClass.my_method = safe_decorator(MyClass.my_method)
    

    然后,您可以从任何类定义中将这个装饰器重用于您想要的任何方法。这就是@ 符号或多或少的作用:)

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:
      def safe_method(self, *args):
        result = self.my_method(*args)
        if result is None: raise ValueError()
        return result
      
      MyClass.my_method = safe_method
      

      上面发生的事情是您将 MyClass.my_method 替换为另一个调用 my_method 的方法。因此,您会遇到递归错误。

      试试这个:

      MyClass._my_method = MyClass.my_method
      
      def safe_method(self, *args):
          result = self._my_method(*args)
          if result is None:
              raise ValueError()
          return result
      
      MyClass.my_method = safe_method
      

      【讨论】: