我在一系列类方法中有一组重复的冗长的 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
获取实际方法给定字符串 methname
。
getattr(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/