python-2.7 - 在 python 2.7 中,如何包装类实例方法或用 try/except block 装饰它?

标签 python-2.7 wrapper decorator try-except instance-methods

我在一系列类方法中有一组重复的冗长的 try/except1/except2/etc block ,这些方法的区别仅在于在外部类实例上调用的外部类方法。下面是一个简化版本(实际上我正在处理 4 个异常和 8 个方法,仅因调用的实例方法而有所不同):

class MyClass(object):
    def __init__(self):
        self.arg = 'foo'

    def method1(self, arg1):
        err = -1
        y = None
        try:
            x = AnOutsideClass(self.arg)     # Creates a class instance of an imported class
            y = x.outsideclassmethod1(arg1)  # Calls an instance method that returns another different class instance
        except MyException1:
            x.dosomething() # Needed to handle error
        except MyException2:
            err = 0
        finally:
            del x
        return y, err

    def method2(self, arg1, arg2, arg3):
        err = -1
        y = None
        try:
            x = AnOutsideClass(self.arg)
            y = x.outsideclassmethod2(arg1, arg2, arg3)  # This is the only thing changed
                                                         # A different method with different argument requirements
        except MyException1:
            x.dosomething()
        except MyException2:
            err = 0
        finally:
            del x
        return y, err

    def method3 ...

我一直在尝试通过使用嵌套函数、装饰器等将这两个语句包装在 try: 代码部分中来压缩此代码的各种方法,但由于我遇到了麻烦,似乎失败了翻译其他示例是因为:1)正在创建一个稍后需要在 except block 之一中使用的类实例,2)正在调用实例方法,3)我需要返回实例方法的结果。

有没有办法通过 functools 或描述符或任何其他方式来完成此操作?我目前有一个笨重的实现,带有一个扩展的 if/elif block ,它根据我在包装函数中使用的整数代码来选择实例方法,但我认为必须有一种更优雅的方法。我对 Python 比较陌生,很茫然......

最佳答案

您可以使用函数工厂(即返回函数的函数)。

def make_method(methname):
    def method(self, *args):
        err = -1
        y = None
        try:
            x = AnOutsideClass(self.arg)     # Creates a class instance of an imported class
            y = getattr(x, methname)(*args)  # Calls an instance method that returns another different class instance
        except MyException1:
            x.dosomething() # Needed to handle error
        except MyException2:
            err = 0
        finally:
            del x
        return y, err
    return method

class MyClass(object):
    def __init__(self):
        self.arg = 'foo'
    method1 = make_method('outsideclassmethod1')
    method2 = make_method('outsideclassmethod2')

make_method以字符串形式传递外部方法名称。 getattr 使用(在 method 内)从 x 获取实际方法给定字符串 methnamegetattr(x, 'foo')相当于 x.foo .

*def method(self, *args)告诉 Python method可以接受任意数量的位置参数。 里面method , args是一个元组。 *y = getattr(x, methname)(*args)告诉 Python 传递 args 中的元素作为 getattr(x, methname) 返回的方法的单独参数。 *解包运算符在the docs, here中进行了解释。 ,以及 this blog .

关于python-2.7 - 在 python 2.7 中,如何包装类实例方法或用 try/except block 装饰它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26745368/

相关文章:

python - Django: 'str' 对象没有属性 'user'

python - Django-CMS apphooks 菜单和反向

python - 如果我用re.findall 怎么注册才能不分开点

c# - Tesseract 3.02 无法加载 DLL

python - 那是奎因还是什么?

typescript 注释

python-2.7 - 由于 "ImportError: No module named parse"无法安装 pip

python - 匹配两个单独列表中的子序列

java - 在循环中使用 Integer 有什么区别吗?

ruby - 学习如何在 ruby​​ 中设计好的 API 包装器的资源