【问题标题】:Python inheritance, metaclasses and type() functionPython 继承、元类和 type() 函数
【发布时间】:2012-12-21 08:40:01
【问题描述】:

我不明白为什么下面的代码会以特定方式运行,如下所述:

from abc import ABCMeta   

class PackageClass(object):
    __metaclass__ = ABCMeta        

class MyClass1(PackageClass):
    pass

MyClass2 = type('MyClass2', (PackageClass, ), {})

print MyClass1
print MyClass2

>>> <class '__main__.MyClass1'> 
>>> <class 'abc.MyClass2'>

为什么repr(MyClass2)abc.MyClass2(顺便说一句,这不是真的)? 谢谢!

【问题讨论】:

  • 这里的项目结构似乎完全无关紧要。我建议删除该部分并将其全部作为 1 个模块(所描述的行为仍然存在)。
  • @mgilson 感谢您的关注,已更新。
  • 而且,作为旁注,这种行为在 python3.x 中仍然存在(我刚刚测试过)
  • @mgilson 它不在我的系统上 - 我使用 cpython 3.1、3.2 和 3.3 得到 &lt;class '__main__.MyClass2'&gt; .
  • 更简单的测试用例:type('bar', (ABCMeta('foo', (object,), {}),), {})

标签: python class python-import abc


【解决方案1】:

问题源于ABCMeta 覆盖__new__ 并在那里调用其超类构造函数(type())。 type() 从其调用上下文1 中为新类派生__module__;在这种情况下,type 调用似乎来自abc 模块。因此,新类将__module__ 设置为abc(因为type() 无法知道实际的类构造发生在__main__)。

简单的方法是在创建类型后自己设置__module__

MyClass2 = type('MyClass2', (PackageClass, ), {})
MyClass2.__module__ = __name__

我还建议提交错误报告。

相关:Base metaclass overriding __new__ generates classes with a wrong __module__Weird inheritance with metaclasses

1:type 是在 C 中定义的类型对象。它的 new method 使用当前全局 __name__ 作为 __module__除非它调用元类构造函数。

【讨论】:

  • 非常感谢@nneonneo 这么详细的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 2016-07-19
  • 1970-01-01
  • 2020-07-26
相关资源
最近更新 更多