数据类对象 属性 别名
Dataclass object property alias
我正在做一个项目来了解更多关于 Python dataclasses
的工作。具体来说,我试图将 API 响应表示为 dataclass
对象。但是,由于 API 响应的结构,我 运行 遇到了问题。
这是来自 API 的示例响应:
{
"@identifier": "example",
"@name": "John Doe",
}
某些字段的名称中包含特殊字符。这意味着我无法直接映射 dataclass
的属性,因为 属性 名称 (SyntaxError
).
中不允许使用 @
等特殊字符
有没有办法为我的 dataclass
属性定义别名,以便我可以将 API 响应直接映射到 dataclass
对象?还是需要先清理响应?
事实上,不仅对象的属性名称中不能包含特殊字符,变量也是如此。在 Python 中,变量名中只允许字符 a-z
、A-Z
、0-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')
我正在做一个项目来了解更多关于 Python dataclasses
的工作。具体来说,我试图将 API 响应表示为 dataclass
对象。但是,由于 API 响应的结构,我 运行 遇到了问题。
这是来自 API 的示例响应:
{
"@identifier": "example",
"@name": "John Doe",
}
某些字段的名称中包含特殊字符。这意味着我无法直接映射 dataclass
的属性,因为 属性 名称 (SyntaxError
).
@
等特殊字符
有没有办法为我的 dataclass
属性定义别名,以便我可以将 API 响应直接映射到 dataclass
对象?还是需要先清理响应?
事实上,不仅对象的属性名称中不能包含特殊字符,变量也是如此。在 Python 中,变量名中只允许字符 a-z
、A-Z
、0-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')