我想将Python对象转换为JSON格式。
使用属性定义类 User 的私有属性。方法 to_Json()我找到了here
class User:
def __init__(self):
self._name = None
self._gender = None
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
@property
def gender(self):
return self._gender
@gender.setter
def gender(self, gender):
self._gender = gender
def to_Json(self):
return json.dumps(self, default=lambda o: o.__dict__, allow_nan=False, sort_keys=False, indent=4)
使用此类和方法的输出是:
{
"_name": "Peter",
"_age": 26
}
摆脱JSON格式下划线的最简单方法是什么? (我想"名称"而不是" _name")删除类中的下划线不是一个选项,因为我收到错误(最大递归深度)。我认为重命名属性的方法可以解决这个问题,但这是最好的解决方案吗?
在json.dumbs之前重命名所有键(参见here)并不是一个实用的方法,因为我的类比上面的例子更复杂。
那么,尽可能快地将Python对象转换为JSON格式的最佳做法是什么?
答案 0 :(得分:6)
如果您发布的示例代码反映了您的实际代码,那么根本没有任何理由可以使用这些属性。你可以这么做:
class User(object):
def __init__(self):
self.name = None
self.age = None
因为你还没有真正隐藏下划线和属性背后的用户。
如果做需要进行转换,我喜欢在自定义编码器中执行此操作:
class MyEncoder(json.JSONEncoder):
def default(self, o):
return {k.lstrip('_'): v for k, v in vars(o).items()}
json_encoded_user = json.dumps(some_user, cls=MyEncoder)
答案 1 :(得分:4)
在Python中,您通常不使用属性作为基本属性。您可以将name
和age
保留为可直接访问的属性。除非您在获取或设置时需要转换数据,否则无需将它们包装在property
个对象中。
如果您有充分的理由使用带下划线的属性但将它们反映为JSON词典,则可以在转换为字典时转换字典:
object_dict = lambda o: {key.lstrip('_'): value for key, value in o.__dict__.items()}
return json.dumps(self, default=object_dict, allow_nan=False, sort_keys=False, indent=4)
请注意,这对防止碰撞没有任何作用。如果您的实例同时拥有_name
和name
属性,那么您将会破坏其中一个属性。
答案 2 :(得分:0)
我遇到了类似的问题,但是我有两个下划线字符的私有字段。
class User:
def __init__(self, id, name):
self.id = id
self.name = name
@property
def id(self):
return self.__id
@id.setter
def id(self, id):
self.__id = id
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
因此,我的json编码器略有不同
from json import JSONEncoder
def beautify_key(str):
index = str.index('__')
if index <= 0:
return str
return str[index + 2:]
class JsonEncoder(JSONEncoder):
def default(self, o):
return {beautify_key(k): v for k, v in vars(o).items()}
完整答案是here。