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
.
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