Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Dynamically create class while providing arguments to __init__subclass__()

How can I dynamically create a subclass of my class and provide arguments to its __init_subclass__() method?

Example class:

class MyClass:
    def __init_subclass__(cls, my_name):
        print(f"Subclass created and my name is {my_name}")

Normally I'd implement my subclass as such:

class MySubclass(MyClass, my_name="Ellis"):
    pass

But how would I pass in my_name when dynamically creating a subclass of MyClass using a metaclass? Normally I could use type() but it doesn't have the option of providing my_name.

MyDynamicSubclass = type("MyDynamicSubclass", (MyClass,), {})
like image 548
Ellis Percival Avatar asked Aug 18 '20 17:08

Ellis Percival


1 Answers

The basic documentation for type does not mention that it accepts an unlimited number of keyword-only arguments, which you would supply through the keywords in a class statement. The only place this is hinted in is in the Data Model in the section Creating the class object:

Once the class namespace has been populated by executing the class body, the class object is created by calling metaclass(name, bases, namespace, **kwds) (the additional keywords passed here are the same as those passed to __prepare__).

Normally, you would not use this feature with type exactly because of __init_subclass__:

The default implementation object.__init_subclass__ does nothing, but raises an error if it is called with any arguments.

Since you have overriden the default implementation, you can create your dynamic class as

MyDynamicSubclass = type("MyDynamicSubclass", (MyClass,), {}, my_name="Ellis")
like image 121
Mad Physicist Avatar answered Sep 30 '22 12:09

Mad Physicist