元类 __init__ 方法的 dct 参数的目的是啥?

Posted

技术标签:

【中文标题】元类 __init__ 方法的 dct 参数的目的是啥?【英文标题】:What is the purpose of the dct argument of a metaclass __init__ method?元类 __init__ 方法的 dct 参数的目的是什么? 【发布时间】:2016-03-21 13:13:11 【问题描述】:

给定一个 Python 2 元类定义为:

class Meta(type):
  def __init__(cls, name, bases, dct):
    pass

dct 参数的目的是什么?根据我的发现,它包含与cls.__dict__ 相同的信息。不同之处在于,对dct 进行更改对具体类没有影响,但向cls.__dict__ 添加内容(即通过cls.__dict__['a']=Truecls.a=True)会产生影响。

class Meta(type):
  def __init__(cls, name, bases, dct):
    cls.a = True
    dct['b'] = True

class Test(object):
  __metaclass__ = Meta

t = Test()
print t.a
print t.b  # Raises an AttributeError

是否存在不同的情况?

【问题讨论】:

【参考方案1】:

dct 参数为您提供原始类命名空间,因此它并没有真正用于元类__init__,因为该类已经在__new__ 中创建。 dctcls.__dict__ 可能相等,但它们不是同一个字典。在您可能需要原始命名空间中包含的信息而不需要由 __new__ 方法或父元类执行任何操作的情况下,它可能很有用。

如果__new__ 方法向类添加属性(在创建之后),它们可能会有所不同。

【讨论】:

如果在调用super(..).__new__() 之前将条目添加到__new__ 中的dct,那么__init__ 中的dct 将包含它。但是,如果调用了super().__init__ 并且thendct 添加了一些内容,那么在__init__ 中它将出现在dct 中,但不在cls.__dict__ 中。无论哪种方式,dct 参数到 __init__ 已从原始类命名空间更改。

以上是关于元类 __init__ 方法的 dct 参数的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

调用元类基时, object.__init__() 不带参数

Tensorflow 错误:TypeError:__init__() 得到了一个意外的关键字参数“dct_method”[关闭]

派生类的类/元类方法装饰器

python元类继承问题

元类的“__init_subclass__”方法在此元类构造的类中不起作用

元类中的属性()设置器问题