【问题标题】:Getting the name of a class which has a meta class获取具有元类的类的名称
【发布时间】:2019-05-29 07:41:18
【问题描述】:

假设我用这样的元类定义了一个类A

class Meta(type):
    pass

class A(metaclass=Meta):
    pass

然后,当我尝试访问 A 类的名称时,我得到了元类的名称:

A.__class__.__name__
#  'Meta'

但是,它不应该给我A,我定义的类吗?

注意:我尝试使用A.__mro__[0].__name__,它确实给了我A,但我仍然很困惑为什么A.__class__ 给了我元类名称。有人对此有解释吗?

【问题讨论】:

  • a = A()print(a.__class__.__name__) ... 'A' - class P: pass ... print(P.__class__.__name__)typeP 如果您使用实例 ... 似乎合法
  • 哦,是的。有没有办法在不实例化和不使用__mro__的情况下获取类名?
  • 使用A.__name__ ?
  • 啊……这正是我所缺少的。不知道我是怎么错过的。随意写这个作为答案。
  • 因为A的是元类。所以 name 将是元。一个类对象是一个实例,就像任何其他的一样,所以就像你做了a = A()a.__class__.__name__ 会给你A

标签: python python-3.x metaclass


【解决方案1】:

__class__dunder 报道:

类实例所属的类。

引用instance.__class__

class A 属于它的元类的类 - 只有 A 的实例属于类 A 本身。

a = A() 
print(a.__class__.__name__) # 'A' 
print(A.__class__.__name__) # 'Meta'

class P: pass 

print(P.__class__.__name__) # type 
print(P().__class__.__name__) # P

要获取类本身的名称,只需使用

A.__name__

如果你真的需要的话。


我仍然可以摸索所有 answerWhat are metaclasses in Python? - 也许它可以帮助你。

【讨论】:

    【解决方案2】:

    A 已经是类 - 它的名称在 A.__name__ 下。 如果您尝试A.__class__.__name__,您将获得A 是实例的类(即它的元类)的名称。

    A.__mro__[0].__name__ 将遵循类 A 的“方法解析顺序” - __mro__ 对象是一个元组,其中包含从定义的类本身开始并以 object 结束的所有类层次结构。因此,A.__mro__[0] 将始终是 A 本身 - 而 A.__mro__[0].__name__A.__name__ 相同。

    __name____qualname__ 属性是可写属性:例如,在创建类后更改 { __qualname__ 将更改该类实例的默认 __repr__。虽然它们在语言定义中并且“活”在类的插槽中(不在它的字典中),但 可能 创建一个 __name__ 属性(我的意思是,内置的 @987654337 @对象或任何其他描述符)将动态更改类的__name__属性(但不是__qualname__ - 这必须是类的属性,并且必须是字符串)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多