Python 工厂 class 继承

Python factory class inheritance

如何检查 class 是否是由工厂 class 创建的 parent 的 child?

考虑以下简单示例:

from itertools import count
def basefactory():
    class Base:
        _idc = count(0)
        def __init__(self):
            self._id = next(self._idc)
    return Base

然后我使用工厂 class:

创建 children
class A(basefactory()):
    def __init__(self):
        super().__init__()

class B(basefactory()):
    def __init__(self):
        super().__init__()

我如何测试 AB 是否是工厂 class 创建的 class 的 children?
如果没有工厂 class 我会使用:issubclass(A, Base)) 但当然这不适用于工厂 class,因为 Base 没有在全局 [=89= 中定义].

此设置的原因是我希望 AB 有不同的 _idc 计数器来为每个实例生成连续的 _ids child classes.
如果 AB 直接继承自 Base,则计数器是共享的。让我用一个例子来说明我的意思。

使用上述工厂 class 设置,如果我这样做:

ll = [A(), A(), B(), B()]   
for e in ll:
    print(e._id, end=", ")

它打印:0, 1, 0, 1, 。相反,如果我在全局 space 和 AB 中移动 Base 直接继承自 Base,则先前的代码打印:0, 1, 2, 3, .

我希望 _id0, 1, 0, 1, ,这就是我使用原厂 class 设置的原因。 在我的真实情况下,我不只有 AB(我有 10 个 class 由工厂 class 创建,它们将来可能会增加),所以我不想重复自己并初始化每个 child.

中的计数器

但是我还需要断言 class 是否是 Base 的 child,或者换句话说,它是否是通过工厂 class 创建的。这就是问题所在。是否可以通过使用 issubclass 检查 class 层次结构来实现?或者我需要更改设置或使用评论中建议的解决方法?

关于提议的副本

我不认为是 Understanding Python super() with __init__() methods 的副本。我知道 super 的作用,但在这种特定情况下没有用。我希望每个 child class 都有一个不同的计数器,我看不出引用 parent class 有什么帮助。
也许它有帮助(如果有,请 post 回答),但由于提议的副本不涉及工厂 classes,我认为这个问题仍然不同。

好吧,我不知道如何正确访问此信息,但是在键入 help(A) 时,您会得到 Base

Help on class A in module __main__:
class A(Base)
 |  Method resolution order:
 |      A
 |      Base
 |      builtins.object
 |  
 |  Methods inherited from Base:
 |  
 |  __init__(self)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from Base:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

我知道一定可以正常访问它

我认为装饰器会做你想做的事情(向 class 添加一个实例计数器),而不是生成不必要的基数的工厂函数 class.

from itertools import count

def add_counter(cls):
    cls._idc = count(0)
    old_init = cls.__init__
    def __init__(self, *args, **kwargs):
        old_init(self, *args, **kwargs)
        self._id  = next(self._idc)
    cls.__init__ = __init__
    return cls

@add_counter
class A:
    pass

@add_counter
class B:
    pass

ll = [A(), A(), B(), B()]
for e in ll:
    print(e._id, end=", ")