如何编写适应成员类接口的容器/包装器类?

问题描述

| 我正在写一个包装另一个类的对象的类。目的是要更改其某些方法行为,同时能够扩展其所有其他接口。我不使用继承,因为内部类对象可能会死亡,并且外部类需要能够用活动对象替换它而不破坏自身。 所以我有:
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
    

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...