需要一种从棉花糖加载函数而不是字典获取python对象的方法,而无需使用post_load装饰器

bha*_*iya 5 python marshmallow

class ProfileSchema(Schema):

    id = fields.Integer()
    first_name = fields.String(required=True)
    last_name = fields.String()
    phone = fields.Str()
    email = fields.Email()
    gender = fields.String()
    city = fields.Str()
    state = fields.Str()
    country = fields.Str()
    age = fields.Int()
    id_proof = fields.Str()
    id_number = fields.Str()
    id_kyc_url = fields.Str()
    image_url = fields.Str()
    profile_type = fields.Str()
    country_code = fields.String()

    @validates('gender')
    def validate_gender(self, value):
        """
        validates gender
        :param value:
        :return:
        """
        if value not in genders:
            raise ValidationError('Incorrect gender value it should be either Male or Female')

    @post_load
    def make_profile(self, data):
        """
        make profile obj
        :param data:
        :return:
        """
        return Profile(**data)
Run Code Online (Sandbox Code Playgroud)

在以上架构中,我使用post_load将dict转换为对象。无论如何,不​​使用post_load装饰器就能得到它吗?

inf*_*ith 5

如果我理解正确的话,那么您遇到的问题不是 post_load 装饰器,而是维护两个对象定义的冗余。如果是这种情况,您可以使用命名元组数据类来实现您想要的。您仍然可以在架构上定义 post_load 方法,但不再需要维护第二个类定义。

命名元组解决方案

from collections import namedtuple

def make_object(class_name, members):
    obj = namedtuple(class_name, ' '.join(members.keys()))
    for k, v in members.items():
        setattr(obj, k, v)
    return obj
Run Code Online (Sandbox Code Playgroud)

数据类解决方案

from dataclasses import make_dataclass

def make_object(class_name, members):
    obj = make_dataclass(class_name, [(k, type(v)) for k,v in members.items()])
    for k, v in members.items():
        setattr(obj, k, v)
    return obj
Run Code Online (Sandbox Code Playgroud)
class ProfileSchema(Schema):

    id = fields.Integer()
    first_name = fields.String(required=True)
    last_name = fields.String()
    phone = fields.Str()
    email = fields.Email()
    gender = fields.String()
    city = fields.Str()
    state = fields.Str()
    country = fields.Str()
    age = fields.Int()
    id_proof = fields.Str()
    id_number = fields.Str()
    id_kyc_url = fields.Str()
    image_url = fields.Str()
    profile_type = fields.Str()
    country_code = fields.String()

    @validates('gender')
    def validate_gender(self, value):
        """
        validates gender
        :param value:
        :return:
        """
        if value not in genders:
            raise ValidationError('Incorrect gender value it should be either Male or Female')

    @post_load
    def make_profile(self, data):
        """
        make profile obj
        :param data:
        :return:
        """
        return make_object(data)
Run Code Online (Sandbox Code Playgroud)