首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dataclass对象属性别名

Dataclass对象属性别名
EN

Stack Overflow用户
提问于 2021-04-08 17:47:13
回答 3查看 868关注 0票数 1

我正在做一个项目,学习更多关于使用Python dataclasses的知识。具体地说,我试图将API响应表示为dataclass对象。然而,由于API响应的结构,我遇到了一个问题。

以下是来自API的示例响应:

代码语言:javascript
复制
{
    "@identifier": "example",
    "@name": "John Doe",
}

某些字段的名称中包含特殊字符。这意味着我不能直接映射我的dataclass的属性,因为属性名(SyntaxError)中不允许使用诸如@之类的特殊字符。

有没有办法为我的API属性定义一个别名,这样我就可以将dataclass响应直接映射到dataclass对象?还是有必要先清理响应?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-04-08 18:11:51

有一个dataclasses-json,它允许您为属性设置别名:

代码语言:javascript
复制
from dataclasses import dataclass, field
from dataclasses_json import config, dataclass_json


@dataclass_json
@dataclass
class Person:
    magic_name: str = field(metadata=config(field_name="@name"))
    magic_id: str = field(metadata=config(field_name="@identifier"))


p = Person.from_json('{"@name": "John Doe", "@identifier": "example"}')
print(p.magic_name)
print(p.to_json())

输出:

代码语言:javascript
复制
John Doe
{"@name": "John Doe", "@identifier": "example"}
票数 2
EN

Stack Overflow用户

发布于 2021-04-08 18:02:06

事实是,不仅对象的属性的名称中不能有特殊字符,变量也不能。在Python中,变量名中只允许使用字符a-zA-Z0-9_,如果您尝试这样做(v@r = 3),如您所说,您将得到SyntaxError。另请注意,变量名中允许使用数字,但变量开头不允许使用数字:

代码语言:javascript
复制
# Ok
test0 = 'Hello World!'
# SyntaxError
0test = 'Goodbye Moonman!'

我建议更改属性的名称,从您的dict键中删除特殊字符,如@。因为最后,您需要在属性名称中添加特殊字符的目的是什么?

也许你可以使用Python object的__getitem____setitem__魔法方法来解决这个问题:

代码语言:javascript
复制
class Object():
    def __init__(self, props):
        self._props = props
    def __getitem__(self, i):
        return self._props[i]

因此,您现在可以使用以下内容:

代码语言:javascript
复制
x = {'Hello': 'World!', '@oodby&': 'Moonman!'}
x = Object(x)

print(x['Hello'])      # World!
print(x['@oodby&'])    # Moonman!

也许这并不完全是你想要的,尽管这可能有它的优点。例如,您可以定义一些类方法来处理self._props

有关__getitem__ here的更多信息:)

票数 0
EN

Stack Overflow用户

发布于 2021-04-08 18:31:26

添加一个'clean‘函数,并用它包装API响应字典。

该解决方案不需要外部库。

代码语言:javascript
复制
from dataclasses import dataclass

api_response = {
    "@identifier": "example",
    "@name": "John Doe",
}


def clean(data: dict) -> dict:
    def _clean(key):
        return key[1:]

    result = {}
    for k, v in data.items():
        result[_clean(k)] = v
    return result


@dataclass
class Response:
    name: str
    identifier: str


res = Response(**clean(api_response))
print(res)

输出

代码语言:javascript
复制
Response(name='John Doe', identifier='example')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67001442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档