【问题标题】:How to define a class with dynamic attributes?如何定义具有动态属性的类?
【发布时间】:2020-05-04 11:18:02
【问题描述】:

在我的项目中,我需要创建一个属性由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访问。

【问题讨论】:

  • 究竟什么是“嵌套”?
  • marshmallow 进行了一些繁重的元编程,包括元类(即在创建类时运行)。您确定仅需要MSchema.sensor 和MSchema.serial_interface 才能访问,还是在创建课程时需要它们?
  • @Ivan Nested 是 Fl​​ask 框架的 Field 类。
  • @MisterMiyagi,marshmallow 有元类,所以我在创建类时需要这些属性
  • 我想知道是否有人考虑过扩充class 语句的定义以允许class MSchema(...): **class_attributes 之类的东西?

标签: python class-attributes


【解决方案1】:

您可以直接调用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

【讨论】:

    【解决方案2】:

    不完全确定我是否 100% 理解了这个问题,但您是否尝试过使用 setattr()?

    示例代码如下所示:

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

    setattr(object, string, value) 接受一个对象来设置属性,一个字符串作为属性名称,一个任意值作为属性值。

    【讨论】:

    • 这不会让元类有机会在必要时处理属性。
    猜你喜欢
    • 2019-04-05
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    相关资源
    最近更新 更多