Reputation: 714
In my project, I need to create a class with attributes passed by a dict
, something like this:
class_attributes = {"sensor": Nested(Sensor),
"serial_interface": Nested(SerialInterface)}
class MSchema(marshmallow.ModelSchema):
class Meta:
model = cls
attr = class_attributes
I need that "sensor" and "serial_interface" to be in the class, and can be access using MSchema.sensor
or MSchema.serial_interface
.
Upvotes: 0
Views: 183
Reputation: 530823
You can call the metaclass of ModelSchema
directly, rather than defining the class declaratively using a class
statement.
m = marshmallow.ModelSchema
class_attributes = {
"sensor": Nested(Sensor),
"serial_interface": Nested(SerialInterface)
}
m = marshmallow.ModelSchema
mc = type(m)
MSchema = mc('MSchema', (m,), {
'Meta': type('Meta', (), {'model': cls}),
**class_attributes
})
In case you aren't aware, a class
statement is just a declarative syntax for calling type
(or some other metaclass) with 3 arguments: the name of the class, a tuple of parent classes, and a dict
of class attributes. The class
statement evaluates its body to produce the dict, then calls type
(or another given metaclass), and binds the return value to the name. Some simpler examples:
# Foo = type('Foo', (), {})
class Foo:
pass
# Foo = Bar('Foo', (), {})
class Foo(metaclass=Bar):
pass
# Foo = Bar('Foo', (Parent,), {'x': 3})
class Foo(Parent, metaclass=Bar):
x = 3
# def foo_init(self, x):
# self.x = x
# Foo = Bar('Foo', (), {'__init__': foo_init})
class Foo(metaclass=Bar):
def __init__(self, x):
self.x = x
Upvotes: 3
Reputation: 313
Not entirely sure I understand the question to 100%, but have you tried using setattr()?
Example code would look like the following:
m_schema = MSchema()
for key, value in class_attributes.items():
setattr(m_schema, key, value)
setattr(object, string, value)
takes an object to set attributes on, a string for the attribute name, and an arbitrary value as the attribute value.
Upvotes: 0