如何编写适应成员类接口的容器/包装类?
我正在编写一个包含另一个类的对象的类。目的是改变它的一些方法行为,同时能够扩展它的所有其他接口。我没有使用继承,因为内部类对象可能会消亡,而外部类需要能够用活动对象替换它而不破坏自身。
所以我有:
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()
问题是如何扩展 goo 而不显式重写,因为我可能有大量我不知道的其他此类方法。
实际上,在阅读下面的一些反馈后,我意识到我没有使用很棒的函数getattr。但是,我不太明白为什么下面的建议似乎都使用如此复杂的版本。为什么不能这么简单:
def __getattr__( self, name ):
if self.inner:
return getattr( self.inner, name )
else:
raise Exception( 'attribute %s not found' % name )
I'm writing a class that wraps around an object of another class. The intend is to change some of its method behaviors while able to extend all of its other interfaces. I'm not using inheritance because the inner class object can die and outer class needs to be able to replace it with a live one without destroying itself.
so I have:
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()
The question is how to extend goo w/o explicitly rewrite as I may have tons of other such methods I'm not aware of.
Actually after reading some of the feedbacks below, I realized I'm not using the great function getattr. However, I don't quite follow why the suggestions below all seem to use such a complicated version. Why can't it be as simple as:
def __getattr__( self, name ):
if self.inner:
return getattr( self.inner, name )
else:
raise Exception( 'attribute %s not found' % name )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的解决方案类似于@khachik加上一些方法缓存。
代码未经测试,请将其视为伪代码。
My solution is similar to @khachik plus some method caching.
Code is untested treat it as pseudo code.
类似下面的代码可以满足您的要求,但是:1)它很丑陋; 2)不是线程安全的; 3)它陷入循环,直到
Inner
中的某个方法引发异常(这不是由于实现而是由于发布的最初想法); 4)还有一些避免使用它的理由:)Something like the code below does what you want, but: 1) it is ugly; 2) it is not thread safe; 3) it falls into a loop until some method from
Inner
raises an exception (this is not due to the implementation but due to the initial idea posted); 4) some more reasons to avoid using it :)