这个问题在StackExchange上被拒绝了,我还没有在StackOverflow上找到答案。
注意:代码 工作,我在运行时询问有关扩展类实例的想法,更好的选项和意见(性能,可靠性)。
例如,让我们说我原来的课程是Foo,我想"延伸它"与酒吧。
我现在的具体限制是:
我想知道是否与新,元类或混合内容有关。但是我还没有做到这一点。
用作基础:
class Foo:
def foo(self): return 'foo'
class Bar:
def bar(self): return self.foo() + 'bar'
foo = Foo()
它可以工作,但它创建了一个新对象,我想不这样做(我认为测试是无用的开销):
class Bar(Foo, object):
def __init__(self, foo):
self.__foo = foo
def __getattr__(self, name):
try:
return getattr(self.__foo, name)
except:
raise AttributeError
def bar(self):
return self.foo() + 'bar'
bar.foo() # OK
bar.bar() # OK
isinstance(bar, Foo) # OK
isinstance(bar, Bar) # OK
几乎可以使用,但Bar不会出现在继承中:
foo.__class__.__dict__.update(Bar.__dict__)
foo.bar() # does work
isinstance(foo, Foo) # True
isinstance(foo, Bar) # False :(
几乎,但Bar不会出现在继承中,我必须测试我修补的属性是否可以调用:
for k, v in Bar.__dict__.iteritems():
if callable(v):
setattr(foo, k, types.MethodType(v, foo))
foo.foo() # OK
foo.bar() # OK
isinstance(foo, Foo) # OK
isinstance(foo, Bar) # False
请赐教。
答案 0 :(得分:3)
CAVEAT:这不是简洁的编程!但你知道: - )
最简单的方法是让Bar成为Foo的子类,然后动态更改实例的类型:
class Foo:
def foo(self): return 'foo'
class Bar(Foo):
def bar(self): return self.foo() + 'bar'
foo = Foo()
foo.__class__ = Bar
print foo.bar()
回应评论中的问题:
>>> class Foo:
... def foo(self): return 'foo'
...
>>> class Bar(Foo):
... def bar(self): return self.foo() + 'bar'
...
>>> foo = Foo()
>>>
>>> foo.__class__ = Bar
>>>
>>> print foo.bar()
foobar
>>> isinstance(foo, Bar)
True
>>> isinstance(foo, Foo)
True
回应另一条评论:是的,这真的很容易:)
答案 1 :(得分:2)
如果您希望isinstance工作,可以将栏添加到Foo.__bases__
:
class Foo:
def foo(self): return 'foo'
class Bar:
def bar(self): return self.foo() + 'bar'
foo = Foo()
Foo.__bases__ = Foo.__bases__ + (Bar,)
print(foo.bar())
print isinstance(foo, Foo)
print(isinstance(foo, Bar))
foobar
True
True