【问题标题】:In python 2.7, how can I wrap a class instance method or decorate it with a try/except block?在 python 2.7 中,如何包装类实例方法或用 try/except 块装饰它?
【发布时间】:2014-12-31 22:43:05
【问题描述】:

我在一系列类方法中有一组重复的冗长的 try/except1/except2/etc 块,它们的区别仅在于在外部类实例上调用外部类方法。下面是一个简化版本(实际上我正在处理 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)我创建了一个类实例,该实例需要稍后在除块之一中使用,2)我正在调用实例方法,3)我需要返回实例方法的结果。

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

【问题讨论】:

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


    【解决方案1】:

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

    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 以字符串形式传递给外部方法名称。 在给定字符串methname 的情况下,getattr 用于(在method 内部)从x 获取实际方法。 getattr(x, 'foo') 等价于x.foo

    def method(self, *args) 中的 * 告诉 Python method 可以接受任意数量的位置参数。 在methodargs 内部是一个元组。 y = getattr(x, methname)(*args) 中的 * 告诉 Python 将 args 中的元素作为单独的参数传递给 getattr(x, methname) 返回的方法。 * 解包运算符在the docs, herethis blog 中进行了说明。

    【讨论】:

      猜你喜欢
      • 2014-05-31
      • 2019-02-03
      • 2014-06-06
      相关资源
      最近更新 更多