gpt4 book ai didi

python - 在运行时扩展一个实例

转载 作者:太空宇宙 更新时间:2023-11-03 14:17:40 25 4
gpt4 key购买 nike

这个问题在 StackExchange 上被拒绝了,我还没有在 StackOverflow 上找到答案。

注意代码确实有效,我正在询问想法、更好的选择和意见(性能、可靠性)以在运行时扩展类实例。

例如,假设我原来的类是 Foo,我想用 Bar“扩展它”。

我现在的具体约束是:

  • Python 2 兼容,即使我对 Python 3 的细节感到好奇(如果有的话)
  • 我从不同的库中获得了一个对象,我想向其添加功能(注意:这是一个“旧式类”)
  • 我需要它来保留它的 parent ,所以 isinstance(instance, Foo) 继续工作
  • 它不能从第一个类重新运行init(有状态连接)
  • 如果能够测试它对"new"类的继承(即:isinstance(instance, Bar)),那就太好了

我想知道是否与 newmetaclass 或 mix-ins 有关。但我还没有取得任何成就。

我尝试了什么

用作基础:

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 :(

使用 types.MethodType

差不多,但是 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

请赐教。

最佳答案

警告:这不是干净的编程!但你知道 :-)

最简单的做法是让 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

回应另一条评论:是的,真的就是这么简单:)

关于python - 在运行时扩展一个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31907122/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com