数据类对象 属性 别名

Dataclass object property alias

我正在做一个项目来了解更多关于 Python dataclasses 的工作。具体来说,我试图将 API 响应表示为 dataclass 对象。但是,由于 API 响应的结构,我 运行 遇到了问题。

这是来自 API 的示例响应:

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

某些字段的名称中包含特殊字符。这意味着我无法直接映射 dataclass 的属性,因为 属性 名称 (SyntaxError).

中不允许使用 @ 等特殊字符

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

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

# Ok
test0 = 'Hello World!'
# SyntaxError
0test = 'Goodbye Moonman!'

我建议更改属性的名称,从字典键中删除特殊字符,例如 @。因为最后,你需要在属性名称中放置特殊字符有什么用?

也许您可以使用 Python 对象的 __getitem____setitem__ 魔术方法来解决一些问题,如下所示:

class Object():
    def __init__(self, props):
        self._props = props
    def __getitem__(self, i):
        return self._props[i]

所以你现在可以使用这个:

x = {'Hello': 'World!', '@oodby&': 'Moonman!'}
x = Object(x)

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

也许这不是您要找的东西,尽管这可能有其优点。例如,您可以定义一些 class 方法来解决 self._props.

更多关于 __getitem__ :)

dataclasses-json,它允许你给属性起别名:

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

输出:

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

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

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

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)

输出

Response(name='John Doe', identifier='example')