如何检测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 newBasewith its owncountinstance.
内容的提问来源于stack exchange,提问作者Valentino

