问题描述
|
我正在写一个包装另一个类的对象的类。目的是要更改其某些方法行为,同时能够扩展其所有其他接口。我不使用继承,因为内部类对象可能会死亡,并且外部类需要能够用活动对象替换它而不破坏自身。
所以我有:
class Inner():
def foo(): pass
def goo(): pass
class Outer():
self.inner = InnerFactory(innerType)
def foo():
try:
self.inner.foo()
except:
del self.inner
self.inner = InnerFactory(innerType)
self.inner.foo()
问题是如何扩展go / w / o显式重写,因为我可能有很多其他我不知道的方法。
实际上,在阅读了下面的一些反馈后,我意识到我没有使用出色的功能getattr。但是,我不太理解为什么以下所有建议似乎都使用了如此复杂的版本。为什么不能这么简单:
def __getattr__( self,name ):
if self.inner:
return getattr( self.inner,name )
else:
raise Exception( \'attribute %s not found\' % name )
解决方法
类似于下面的代码可以满足您的要求,但是:1)丑陋; 2)它不是线程安全的; 3)陷入循环,直到
Inner
中的某个方法引发异常(这不是由于实现,而是由于最初的想法); 4)一些避免使用它的原因:)
class Inner:
def foo(self):
print \"foo\"
def bar(self):
print \"bar\"
class Outer:
def __init__(self):
self.inner = Inner()
def __getattr__(self,name):
ret = getattr(self.inner,name)
def wrapper(*args):
try:
ret(*args)
except:
del self.inner
self.inner = Inner()
updated = self.__getattr__(name)
updated(*args)
return wrapper
def blah(self):
print \"Blah\"
outer = Outer()
outer.foo()
outer.bar()
outer.blah()
outer.nosuchattr()
,我的解决方案类似于@khachik,外加一些方法缓存。
请注意,很容易通过__ getattr__进入无限循环。
另外,如果需要,您可能想添加线程锁
未经测试的代码将其视为伪代码。
class Outer(object):
def __init__(self):
self.method_cache = {}
self.methods_to_override = [\'foo\',\'goo\']
def __getattr__(self,method_name):
if method_name in self.methods_to_override:
if method_name in self.method_cache:
return self.method_cache[method_name]
else:
def wrapper(*args,**kw):
wrapped = getattr(self.inner,method_name)
try:
return wrapped(*args,**kw)
except InnerDiedError:
self.inner = self.InnerFactory(innerType)
wrapped = getattr(self.inner,method_name)
return wrapped(*args,**kw)
self.method_cache[method_name] = wrapper
return wrapper