2013-11-06 2 views
3

У меня есть класс из библиотеки, скажем MyClass по методу my_method.метод украшения после объявления

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

Я не могу thouch оригинальной реализации, но я хочу, чтобы украсить 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 

Я понимаю, почему, но я не могу решить проблему

ответ

2

Вы можете украсить его так:

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) 

Вы можете затем использовать этот декоратор для любой метод вы хотите из любого определения класса. Это то, что нотация @ делает более или менее :)

Надеюсь, это поможет!

1
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 
+0

это работает, но мне кажется, что это грязный трюк –