如何将带有属性的对象转换为JSON而不使用" _"在Python 3?

时间:2015-08-04 15:18:12

标签: python json

我想将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格式的最佳做法是什么?

3 个答案:

答案 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中,您通常使用属性作为基本属性。您可以将nameage保留为可直接访问的属性。除非您在获取或设置时需要转换数据,否则无需将它们包装在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)

请注意,这对防止碰撞没有任何作用。如果您的实例同时拥有_namename属性,那么您将会破坏其中一个属性。

答案 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