Reputation: 3867
The class
statement takes keyword arguments for various features. For example, the __init_subclass__
function receives keyword arguments passed at the class declaration:
class A(object):
def __init_subclass__(cls, **kwargs):
print(f'{kwargs=}')
class B(A, my_arg=5):
pass
kwargs={'my_arg': 5}
However, doing so prevents dynamic class creation: The type
function does not seem to take the class
keyword arguments. A factory function does, but may conflict with __init_subclass__
or similar when the factory must modify the class.
I would like to use the type()
built-in function in its 3-arguments version to dynamically create a class. However, there seems to be no documented way to pass keyword arguments (like my_arg
in the previous example).
What would be the recommended way of doing it ?
Upvotes: 4
Views: 711
Reputation: 50076
The bare type
is not the equivalent of class
statements in Python3. Use types.new_class
as a functional equivalent of class
statements.
class B(A, my_arg=5):
a = 12 # non-trivial class body
B = types.new_class(
'B',
# base classes of `class` statement
bases=(A,),
# keywords to the `class` statement
kwds={'my_arg': 5},
# the class body as a function
exec_body=lambda body: body.update({'a': 12}),
)
Keep in mind that a class
statement can always be wrapped in a function to allow a parameterised, functional class creation. This also allows to set most special attributes, e.g. the class name via __qualname__
:
def make_b(my_arg, my_a, name=None):
class Parameterized_B(A, my_arg=my_arg):
a = my_a
if name is not None:
__qualname__ = name
return Parameterized_B
B = make_b(5, 12, "B")
Upvotes: 5