You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测Python类是否为工厂类生成的父类的子类?

Solution for Detecting Subclasses of Factory-Generated Base Classes

Great question! The core issue here is that each call to basefactory() returns a new, distinct Base class object—so A.__bases__[0] and B.__bases__[0] are two separate classes, even though they have identical behavior. That’s why issubclass(A, Base) fails (since Base doesn’t exist in the global scope anymore, and even if it did, it wouldn’t match the specific Base instance that A inherits from).

Here are clean, non-intrusive solutions to detect these subclasses while preserving your per-subclass counter setup:


Option 1: Add a Unique Marker Attribute to Factory-Generated Bases

This is the most reliable approach—we’ll add a special class attribute to every Base created by basefactory, then check for this marker when verifying subclasses.

First, modify your factory to include the marker:

from itertools import count

def basefactory():
    class Base:
        _idc = count(0)
        # Unique marker to identify factory-generated Base classes
        _is_factory_generated_base = True
        
        def __init__(self):
            self._id = next(self._idc)
    return Base

Then create a helper function to check for this marker recursively (in case you have subclasses of subclasses):

def is_factory_subclass(cls):
    """Check if a class inherits from any factory-generated Base."""
    for base in cls.__bases__:
        # Check if this base has our marker
        if getattr(base, '_is_factory_generated_base', False):
            return True
        # Recurse to check parent classes of the base
        if is_factory_subclass(base):
            return True
    return False

Test it out:

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

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

class C(A):  # Subclass of a factory-derived class
    pass

print(is_factory_subclass(A))  # True
print(is_factory_subclass(B))  # True
print(is_factory_subclass(C))  # True
print(is_factory_subclass(int)) # False

This preserves your original counter behavior—each subclass still gets its own independent _idc:

a1, a2 = A(), A()
b1, b2 = B(), B()
print(a1._id, a2._id, b1._id, b2._id)  # Output: 0 1 0 1

Option 2: Inspect Class Metadata (Less Reliable)

If you don’t want to add a marker attribute, you can check the class’s origin by inspecting its qualname or closure. This is more fragile (it depends on function names/module structure), but works for simple cases:

def is_factory_subclass_v2(cls):
    for base in cls.__bases__:
        # Check if the base was defined inside basefactory
        if base.__module__ == __name__ and base.__qualname__.startswith("basefactory.<locals>."):
            return True
        if is_factory_subclass_v2(base):
            return True
    return False

Key Takeaways

  • The marker attribute approach is preferred because it’s explicit, stable, and doesn’t rely on implementation details.
  • You don’t need to adjust your core architecture—this solution works seamlessly with your existing factory and subclass setup.
  • Your per-subclass counter behavior remains intact, since each basefactory() call still returns a new Base with its own count instance.

内容的提问来源于stack exchange,提问作者Valentino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:49:12