Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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_Inheritance_Python 2.x_Metaclass - Fatal编程技术网

Python 在什么情况下调用父类中的多个元类?

Python 在什么情况下调用父类中的多个元类?,python,inheritance,python-2.x,metaclass,Python,Inheritance,Python 2.x,Metaclass,行为异常的代码(用Python 2.7.3测试): 其产出: Declaring BaseClass1 Hello Meta1.__new__ ----------------------- Declaring BaseClass2 Hello Meta2.__new__ Hello Meta1.__new__ # WHY WAS IT INVOKED? ----------------------- <class '__main__.Meta1'> 声明BaseClass1

行为异常的代码(用Python 2.7.3测试):

其产出:

Declaring BaseClass1
Hello Meta1.__new__ 
-----------------------
Declaring BaseClass2
Hello Meta2.__new__ 
Hello Meta1.__new__ # WHY WAS IT INVOKED?
-----------------------
<class '__main__.Meta1'>
声明BaseClass1
你好,Meta1.\uuuu新的\uuuu
-----------------------
声明BaseClass2
你好,Meta2.\uuuu新的\uuuuu
你好,Meta1.uuu new_uu35;为什么要调用它?
-----------------------
有关守则的问题:

为什么即使BaseClass2的
\uuuuuuuuuuuuuuuuuuuuuuuuuu
属性设置为Meta2,并且对于其“父类BaseClass1”
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

为什么在BaseClass2定义中同时调用
Meta2.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
Meta1.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

在什么情况下调用父类元类中的方法?

长话短说:

在试图理解元类在我们的项目中是如何工作的同时,我编写了可以在上面找到的代码。(该项目使用Python2.7.3,看起来项目中使用的元类是可靠的,因为它们用于向用户提供API,元类在幕后为用户做了很多事情。)


首先,我试图找到有关元类如何处理继承的文档。Guido van Rossum的以下文章(相当老,但看起来对Python 2.7有效)阐明了在继承的情况下如何选择元类,子类对元类的要求是什么,以及Python在为兄弟类选择元类时可以执行的小技巧:。我在Python中读到的关于元类的这篇文章和其他文章并没有解释我观察到的行为。我想阅读Python解释器代码会有所帮助,但我相信文档的威力,并希望可以避免这种极端的措施。欢迎提供任何描述所观察到的代码行为的材料的答案/指针。

经过大量查找,我想我找到了答案。Python3文档中有这样一个说明

3.3.3.3。确定适当的元类

类定义的适当元类确定如下:

  • 如果没有给出基和显式元类,则使用
    type()
  • 如果给出了一个显式元类,但它不是
    type()
    的实例,那么它就是 直接用作元类
  • 如果将
    type()
    的实例作为显式元类给出,或定义了基,则使用最派生的元类
最派生的元类是从显式指定的元类(如果有)和所有指定基类的元类(即
type(cls)
)中选择的。最派生的元类是所有这些候选元类的子类型。如果没有一个候选元类符合该标准,那么类定义将失败,并出现
TypeError

我认为这仍然适用于Python2(无论如何是v2.7),尽管我在它的文档中找不到类似上面的内容


BaseClass2
定义同时调用
Meta2.\uuuuu new\uuuuu()
Meta1.\uuuuuuuuu new\uuuuuuu()
的原因很简单-
Meta2.\uuuuuu new\uuuuuuuuu()
通过调用
super()显式调用它。但是,为了使它正常工作,您还需要更改
Meta2.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,但是,由于元类冲突,
BaseClass2
的定义在Python 3中会导致
TypeError
(它试图继承元类
Meta1
,但您告诉它使用不相关的元类
Meta2
)。我怀疑Python2的行为在这种情况下是完全错误的。
Declaring BaseClass1
Hello Meta1.__new__ 
-----------------------
Declaring BaseClass2
Hello Meta2.__new__ 
Hello Meta1.__new__ # WHY WAS IT INVOKED?
-----------------------
<class '__main__.Meta1'>