Как определить класс с атрибутами Dynami c? - PullRequest
0 голосов
/ 17 января 2020

В моем проекте мне нужно создать класс с атрибутами, переданными dict, что-то вроде этого:

class_attributes = {"sensor": Nested(Sensor),
                    "serial_interface": Nested(SerialInterface)}
class MSchema(marshmallow.ModelSchema):
    class Meta:
        model = cls

    attr = class_attributes

Мне нужно, чтобы "sensor" и "serial_interface" были в классе и может быть доступ с помощью MSchema.sensor или MSchema.serial_interface.

Ответы [ 2 ]

3 голосов
/ 17 января 2020

Вы можете вызвать метакласс ModelSchema напрямую, вместо того, чтобы декларативно определять класс с помощью оператора class.

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
    })

Если вы не знаете, class оператор - это просто декларативный синтаксис для вызова type (или некоторого другого метакласса) с 3 аргументами: именем класса, кортежем родительских классов и dict атрибутов класса. Оператор class вычисляет свое тело для создания dict, затем вызывает type (или другой заданный метакласс) и связывает возвращаемое значение с именем. Несколько простых примеров:

 # 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
0 голосов
/ 17 января 2020

Не совсем уверен, что я понимаю вопрос на 100%, но вы пытались использовать setattr () ?

Пример кода будет выглядеть следующим образом:

m_schema = MSchema()
for key, value in class_attributes.items():
    setattr(m_schema, key, value)

setattr(object, string, value) принимает объект для установки атрибутов, строку для имени атрибута и произвольное значение в качестве значения атрибута.

...