Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何编写适应成员类接口的容器/包装器类?_Python_Containers_Wrapper - Fatal编程技术网

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

Python 如何编写适应成员类接口的容器/包装器类?,python,containers,wrapper,Python,Containers,Wrapper,我正在编写一个类,它围绕着另一个类的对象。其目的是在能够扩展其所有其他接口的同时,更改其某些方法行为。我不使用继承,因为内部类对象可能会死亡,而外部类需要能够在不破坏自身的情况下用活动对象替换它 因此,我: class Inner(): def foo(): pass def goo(): pass class Outer(): self.inner = InnerFactory(innerType) def foo(): try:

我正在编写一个类,它围绕着另一个类的对象。其目的是在能够扩展其所有其他接口的同时,更改其某些方法行为。我不使用继承,因为内部类对象可能会死亡,而外部类需要能够在不破坏自身的情况下用活动对象替换它

因此,我:

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 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) 它陷入一个循环,直到
内部的某个方法引发异常(这不是由于实现,而是由于发布的最初想法);4) 还有一些避免使用它的原因:)


我的解决方案类似于@khachik加上一些方法缓存

  • 小心,使用_uuu_uuu_uu_uu_uu_u_u_u__u___________)很容易进入无限循环
  • 如果需要,您可能还需要添加线程锁
未测试的代码将其视为伪代码


我不太确定,但可能与此有关。@Space\u C0wb0y的区别在于这里有大量的方法要重写。
除了:
某种pythonic-wise异端邪说吗?我们不应该只捕捉
属性错误
s吗?
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()
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