Suppose I want to define a Python class whose instances have several members of similar form:
class Bar:
def __init__(self):
self.baz=3
self.x=1
self.name=4
I can instead create all members at once using explicit manipulation of __dict__
:
class Bar:
def __init__(self):
self.__dict__.update({name: len(name) for name in ("baz", "x", "name")})
However, if the associated members are class data members, instead of instance members, then I am aware of no analogous way to programmatically mutate Bar.__dict__
:
class Bar:
#Fails with "AttributeError: 'mappingproxy' object has no attribute 'update'"
Bar.__dict__.update({name: len(name) for name in ("baz", "x", "name")})
In Javascript, programmatically manipulating the properties of a constructor is possible, because constructors are just ordinary functions, which are just ordinary objects, and therefore just a mutable dictionary mapping properties to more objects. Is it possible to write analogous code in Python?
CodePudding user response:
I guess you can use a metaclass, a base class with __init_subclass__
or use eval
to create your class. Here's an example using a base class:
class Base:
attrs_to_set: set[str] = set()
def __init_subclass__(cls) -> None:
for attr in cls.attrs_to_set:
setattr(cls, attr, cls.get_attr_value(attr))
@classmethod
def get_attr_value(cls, attr_name: str):
# default, you can change it depending on your use case i guess.
return len(attr_name)
class Bar(Base):
attrs_to_set = {"x", "baz", "name"}
print(Bar.x, Bar.name, Bar.baz)
# prints: 1 4 3