This article有一个片段,显示了如何使用__bases__
来动态更改某些Python代码的继承层次结构,方法是将一个类添加到继承它的类的现有类集合中。好吧,这很难理解,代码可能更清晰:
class Friendly:
def hello(self):
print 'Hello'
class Person: pass
p = Person()
Person.__bases__ = (Friendly,)
p.hello() # prints "Hello"
也就是说,Person
不是从源级别的Friendly
继承,而是通过修改Person类的__bases__
属性在运行时动态添加此继承关系。但是,如果将Friendly
和Person
更改为新样式类(通过从对象继承),则会出现以下错误:
TypeError: __bases__ assignment: 'Friendly' deallocator differs from 'object'
在运行时更改继承层次结构时,在新样式类和旧样式类之间似乎有点像是indicate some incompatibilities。具体来说:"New-style class objects don't support assignment to their bases attribute"。
我的问题是,是否可以使用Python 2.7+中的新样式类(可能使用__mro__
属性)使上述友好/个人示例正常工作?
免责声明:我完全意识到这是一段晦涩难懂的代码。我完全意识到,在实际的生产中,类似这样的代码技巧往往难以阅读,这纯粹是一个思想实验,对于funzies来说,可以学习一些Python如何处理与多重继承相关的问题。
我也一直在努力解决这个问题,并且对你的解决方案很感兴趣,但是Python3把它从我们身边夺走了:
实际上,我有一个合法的需求,需要一个decorator来替换decorated类的(单个)超类。它需要太长的描述才能包含在这里(我尝试过,但无法将其保持到合理的长度和有限的复杂性——这是在许多基于Python的企业服务器的Python应用程序使用的上下文中出现的,其中不同的应用程序需要一些稍微不同的代码变体)
本页的讨论和其他类似的讨论提供了这样的提示:赋值给
__bases__
的问题只发生在没有定义超类(即,其唯一的超类是object)的类上。通过将需要替换其超类的类定义为一个平凡类的子类,我能够解决这个问题(对于Python2.7和3.2):好吧,再说一遍,这不是你通常应该做的,这只是为了提供信息。
Python在实例对象上查找方法由定义该对象的类的
__mro__
属性(esolutionOrder属性)确定。因此,如果我们可以修改Person
的__mro__
,我们将获得所需的行为。类似于:问题是
__mro__
是只读属性,因此setattr不起作用。如果你是一个Python大师,也许有办法解决这个问题,但很明显我没有达到大师的地位,因为我想不出一个。一种可能的解决方法是简单地重新定义类:
这不会修改任何先前创建的
Person
实例,使其具有hello()
方法。例如(只是修改main()
):如果
type
调用的详细信息不清楚,请阅读e-satis' excellent answer on 'What is a metaclass in Python?'。我不能保证其后果,但这段代码符合py2.7.2的要求。
我们知道这是可能的。很酷。但我们永远不会用它!
相关问题 更多 >
编程相关推荐