如果值字符串是有效的 Python 文字,您可以使用 ast.literal_eval 将这些字符串安全地评估为 Python 对象。
import ast
class SomeEntity:
def __init__(self):
self.id = 0
self.name = ""
self.some_attr = {}
def apply_values(entity, list_of_values):
for key, value in list_of_values:
if hasattr(entity, key):
converted = ast.literal_eval(value)
setattr(entity, key, converted)
entity = SomeEntity()
attr_list = [
('id', '42'),
('name', '"the entity"'),
('some_attr', '{"one": 1, "two": 2}'),
]
apply_values(entity, attr_list)
x = entity.id
print(x, type(x))
x = entity.name
print(x, type(x))
x = entity.some_attr
print(x, type(x))
输出
42 <class 'int'>
the entity <class 'str'>
{'one': 1, 'two': 2} <class 'dict'>
请注意,我们也可以将属性名称和值字符串放入dict:
attr_dict = {
'id': '42',
'name': '"the entity"',
'some_attr': '{"one": 1, "two": 2}'
}
apply_values(entity, attr_dict.items())
正如 Alfe 在 cmets 中提到的,该代码忽略了实体属性的类型。这是一个将现有属性类型考虑在内的修改版本。
import ast
class SomeEntity:
def __init__(self):
self.id = 0
self.name = ""
self.some_attr = {}
self.level = 0.0
def apply_values(entity, list_of_values):
for key, value in list_of_values:
if hasattr(entity, key):
type_attr = type(getattr(entity, key))
converted = type_attr(ast.literal_eval(value))
setattr(entity, key, converted)
entity = SomeEntity()
attr_dict = {
'id': '42',
'name': '"the entity"',
'some_attr': '{"one": 1, "two": 2}',
'level': '5',
}
apply_values(entity, attr_dict.items())
for k, v in entity.__dict__.items():
print(repr(k), repr(v), type(v))
输出
'id' 42 <class 'int'>
'name' 'the entity' <class 'str'>
'some_attr' {'one': 1, 'two': 2} <class 'dict'>
'level' 5.0 <class 'float'>