Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.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
Python2中类型的混淆_Python_Python 2.x_Metaclass - Fatal编程技术网

Python2中类型的混淆

Python2中类型的混淆,python,python-2.x,metaclass,Python,Python 2.x,Metaclass,请看下面的示例 class Base(type): def __init__(cls, name, bases, dict_): print 'Base.__init__() with cls %s, name %s...' % (cls, name, ) type.__init__(cls, name, bases, dict_) M = Base('M', (object,), {}) class D1(Base): pass class

请看下面的示例

class Base(type):
    def __init__(cls, name, bases, dict_):
        print 'Base.__init__() with cls %s, name %s...' % (cls, name, )
        type.__init__(cls, name, bases, dict_)

M = Base('M', (object,), {})

class D1(Base):
    pass

class D2(M):
    pass
输出是

Base.__init__() with cls <class '__main__.M'>, name M...
Base.__init__() with cls <class '__main__.D2'>, name D2...
Base.\uuuu init\uuuuuuuu()与cls,名称M。。。
Base.\uuuu init\uuuuuuuuu()与cls,名称D2。。。
我对结果感到很困惑


  • 为什么
    Base.\uuuuu init\uuuuu
    可以为
    D2
    调用,即使我们还没有创建
    D2
    的实例
  • 既然
    Base.\uuuuu init\uuuu
    可以为
    D2
    调用,为什么
    D1
    不能呢

  • Base.\uuuu init\uuuu
    在执行以下操作时第一次被调用:

    M = Base('M', (object,), {})
    
    您正在创建一个
    Base
    的实例,因此它的
    \uuuu init\uuuu
    方法被调用,这并不奇怪

    它在创建
    D2
    时被第二次调用,因为创建一个类调用
    元类的
    \uuuu init\uuuu
    方法(是的,类的类),它是
    D2
    Base
    的一个实例

    由于
    D1
    Base
    的子类型/子类,而不是它的实例,因此它不被称为
    D1

    请注意,将
    Base
    设为
    D1
    的元类而不是其超类时会发生什么:

    class D1(object):
        __metaclass__ = Base
        pass
    
    # Base.__init__() with cls <class 'D1'>, name D1...
    
    D1类(对象):
    __元类\基
    通过
    #Base.\uuuuu init\uuuuuuuuuuu()和cls,名称D1。。。
    
    Base.\uuuu init\uuuu
    在您执行以下操作时第一次被调用:

    M = Base('M', (object,), {})
    
    您正在创建一个
    Base
    的实例,因此它的
    \uuuu init\uuuu
    方法被调用,这并不奇怪

    它在创建
    D2
    时被第二次调用,因为创建一个类调用
    元类的
    \uuuu init\uuuu
    方法(是的,类的类),它是
    D2
    Base
    的一个实例

    由于
    D1
    Base
    的子类型/子类,而不是它的实例,因此它不被称为
    D1

    请注意,将
    Base
    设为
    D1
    的元类而不是其超类时会发生什么:

    class D1(object):
        __metaclass__ = Base
        pass
    
    # Base.__init__() with cls <class 'D1'>, name D1...
    
    D1类(对象):
    __元类\基
    通过
    #Base.\uuuuu init\uuuuuuuuuuu()和cls,名称D1。。。
    
    错误
    Base(参数)
    调用
    Base.\uuu init\uuu
    ..“为什么
    Base.\uuu init\uuu
    可以为
    D2
    调用,即使我们还没有创建
    D2
    的实例,因为您已经创建了
    Base
    的实例。那个实例是
    D2
    Base(参数)
    调用
    Base.\uuu init\uuu
    ..“为什么
    Base.\uuu init\uuu
    可以为
    D2
    调用,即使我们还没有创建
    D2
    的实例,因为您已经创建了
    Base
    的实例。那个实例是
    D2
    。我不熟悉
    元类的工作原理。所以我仍然感到困惑,为什么
    Base。当D2是
    Base
    的一个实例时,调用了\uuuu init\uuuu
    ;即使在阅读之后,因为这里没有使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。所以我仍然感到困惑,为什么
    Base。当D2是
    Base
    的一个实例时,调用了\uuuu init\uuuu
    ;即使在阅读之后,因为这里没有使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    。另一个问题是:
    \uuuuuuuuuuuuuuuu?