在 metaclass 中实例化刚刚创建的 class 会导致 RuntimeError ("super(): empty __class__ cell")

Instantiating a just-created class in a metaclass results in a RuntimeError ("super(): empty __class__ cell")

所以我有这个元class,我想用它来自动注册新组件,即一些基本组件class的子classes。注册新组件时,其 实例 应传递给处理该组件的 register_component() 函数。

Metaclass 代码(精简版):

class AutoRegisteredMeta(type):
    def __new__(metacls, name, bases, attrs):

        # ... (omitted) check if "name" has already been registered ...

        new_class = super().__new__(metacls, name, bases, attrs)
        register_component(name, new_class())  # RuntimeError(super(): empty __class__ cell)
        return new_class

问题是调用 new_class() 会导致错误 - 但并非对所有 class 都是如此。经过一些试验后,我意识到这只有在 subclass 在它自己的 __init__() 方法中调用 super().__init__() 时才会发生。

示例组件和基础class:

class BaseComponent(metaclass=AutoRegisteredMeta):
    def __init__(self):
        # do some work here ...

class ComponentFoo(BaseComponent):
    def __init__(self):
        super().__init__()  # <--- RuntimeError occurs here
        self.foo = 'bar'

我在这里做错了什么?阅读 this 我发现我可能不应该在 metaclass 的 __new__()__init__() 中进行实例化,对吗?这也许可以通过某种方式规避吗?

此外,一些通俗易懂的解释会很好,我不太了解 CPython 实现的内部结构。

提前致谢!

(FWIW,我使用 Python 3.3.6,Ubuntu)


编辑:我正在添加所请求的最小示例,您可以直接 运行 它并自己查看操作中的错误。

#!/usr/bin/env python3


class AutoRegisteredMeta(type):
    def __new__(metacls, name, bases, attrs):
        new_class = super().__new__(metacls, name, bases, attrs)
        new_class()  # <--- RuntimeError can occur here
        return new_class


class BaseComponent(metaclass=AutoRegisteredMeta):
    def __init__(self):
        print("BaseComponent __init__()")


class GoodComponent(BaseComponent):
    def __init__(self):
        print("GoodComponent __init__()")


class BadComponent(BaseComponent):
    def __init__(self):
        print("BadComponent __init__()")
        super().__init__()  # <--- RuntimeError occurs because of this

也许这行得通:

#!/usr/bin/env python3


class AutoRegisteredMeta(type):
    def __new__(metacls, name, bases, attrs):
        new_class = super().__new__(metacls, name, bases, attrs)
        new_class()
        return new_class


class BaseComponent(metaclass=AutoRegisteredMeta):
    def __init__(self):
        print("BaseComponent __init__()")


class GoodComponent(BaseComponent):
    def __init__(self):
        print("GoodComponent __init__()")


class BadComponent(BaseComponent):
    def __init__(self):
        print("BadComponent __init__()")
        super(self.__class__, self).__init__()