【发布时间】:2017-08-11 20:18:48
【问题描述】:
我需要编写一个类来包装来自第三方包的类。通常,第三方类具有返回第三方类实例的方法。这些方法的包装版本必须将这些实例转换为包装类的实例,但我无法使其工作。我正在使用带有新样式类的 Python 2.7。
基于Create a wrapper class to call a pre and post function around existing functions?,我有以下内容。
import copy
class Wrapper(object):
__wraps__ = None
def __init__(self, obj):
if self.__wraps__ is None:
raise TypeError("base class Wrapper may not be instantiated")
elif isinstance(obj, self.__wraps__):
self._obj = obj
else:
raise ValueError("wrapped object must be of %s" % self.__wraps__)
def __getattr__(self, name):
orig_attr = self._obj.__getattribute__(name)
if callable(orig_attr):
def hooked(*args, **kwargs):
result = orig_attr(*args, **kwargs)
if result == self._obj:
return result
return self.__class__(result)
return hooked
else:
return orig_attr
class ClassToWrap(object):
def __init__(self, data):
self.data = data
def theirfun(self):
new_obj = copy.deepcopy(self)
new_obj.data += 1
return new_obj
class Wrapped(Wrapper):
__wraps__ = ClassToWrap
def myfun(self):
new_obj = copy.deepcopy(self)
new_obj.data += 1
return new_obj
obj = ClassToWrap(0)
wr0 = Wrapped(obj)
print wr0.data
>> 0
wr1 = wr0.theirfun()
print wr1.data
>> 1
wr2 = wr1.myfun()
print wr2.data
>> 2
wr3 = wr2.theirfun()
print wr3.data
>> 2
现在为什么theirfun() 第一次工作,第二次却不行? wr0 和 wr2 都是 Wrapped 类型,调用 wr2.theirfun() 不会引发错误,但不会像预期的那样将 1 添加到 wr2.data。
抱歉,我不在寻找以下替代方法:
- 猴子补丁。我的代码库很重要,我不知道如何确保补丁能够通过导入语句的网络传播。
- 为每个第三方包的所有这些棘手的方法编写单独的包装方法。它们太多了。
ETA:有几个有用的答案引用了 _obj 类之外的基础 _obj 属性。然而,这种方法的重点是可扩展性,所以这个功能需要在Wrapper 类中。 myfun 需要按预期运行,而不在其定义中引用 _obj。
【问题讨论】:
标签: python python-2.7 wrapper