1

I have a base class Foo and another base class Bar.

I would like to create two sets of Baz classes (e.g., Baz1, ..., Baz20) such that for each N from 1 to 20, there's a BazN class that inherits from Foo, and also a BazN class that inherits from Bar. So I'd end up with 40 BazN classes, 20 of which are BazNFoo and 20 of which are type BazNBar.

What I have is the below snippet, which explicitly writes each BazN class twice, once inheriting from Foo and once from Bar. My question is, is there a programmatic way to do this writing each BazN class just once? My Baz classes are pretty long.

class Foo:
    def __init__(self):
        # code specific to Foo
    
class Bar:
    def __init__(self):
        # code specific to Bar

class Baz1Foo(Foo):
    def __init__(self):
        super().__init__()
        # code specific to Baz1

class Baz1Bar(Bar):
    def __init__(self):
        super().__init__()
        # code specific to Baz1

class Baz2Foo(Foo):
    ...
5
  • Note: Foo and Bar have non-compatible information so I cannot simply use multiple inheritance (e.g., class Baz1(Foo, Bar)) Commented Dec 4, 2021 at 17:18
  • Having 20 children class from one parent is a very strange design, what different properties would they have ? That isn't a good idea, you shouldn't be finfind a solution for that, but rather a total different way to do it Commented Dec 4, 2021 at 17:18
  • Can I ask why you want to a design like this? This looks a lot like an X/Y Problem... Commented Dec 4, 2021 at 17:22
  • 1
    One use case is if the parents Foo and Bar are two different database base classes and each Baz is a table schema. For example, in sqlalchemy, you can use declarative_base to create a Base class, or create a Base class explicity. Commented Dec 4, 2021 at 17:28
  • Also, apologies if my arbitrary N=20 raised flagrant design questions, the same question applies for just N=2-3 (large) child classes where one would rather not replicate the same child code twice. Commented Dec 4, 2021 at 17:34

1 Answer 1

2

You can create dynamic subclasses using type - however this is relatively advanced and just because it can be done this way, doesn't mean it's a good idea...

# Define a parent class
class Foo():
    def __init__(self):
        print("Init Foo")

    def foo(self):
        print("Method Foo")

# Create a dict to store the sub-classes in (could use globals() instead)
classes = {}
for i in range(2):
    # Create Foo0..Foo2
    classes[f'Foo{i}'] = type(
        f'Foo{i}',
        # Inherit from Foo
        (Foo,),
        # super() must be passed child class object in type construction
        # https://bugs.python.org/issue29944
        { "__init__": lambda self: super(self.__class__, self).__init__() }
    )

# Some proof it works...
for cls in classes.values():
    # Instantiate each class
    i = cls()
    # Print the class info (name)
    print(i.__class__)
    # Call the (inherited) foo method
    i.foo()

    ### OUTPUT:
    # Init Foo
    # <class '__main__.Foo0'>
    # Method Foo
    # Init Foo
    # <class '__main__.Foo1'>
    # Method Foo
    # Init Foo
    # <class '__main__.Foo2'>
    # Method Foo
Sign up to request clarification or add additional context in comments.

2 Comments

Those are subtly different in that they are not dynamically naming the class, or supering the parent class, but they do give some other examples of dynamic class generation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.