简体   繁体   English

如何在Python 3中将没有“_”的带有属性的对象转换为JSON?

[英]How to convert Object with Properties to JSON without “_” in Python 3?

I would like to convert an Python object into JSON-format. 我想将Python对象转换为JSON格式。

The private attributes of the class User are defined using properties. User的私有属性是使用属性定义的。 The method to_Json() I have found here 我在这里找到方法to_Json()

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)

The output using this class and method is: 使用此类和方法的输出是:

{
  "_name": "Peter",
  "_age": 26
}

What is the easiest way to get rid of the underscores in the JSON-format? 什么是摆脱JSON格式下划线的最简单方法? (I want "name" instead of "_name") Removing the underscore in the class is not an option since I get an error (max. recursion depth). (我想要“name”而不是“_name”)删除类中的下划线不是一个选项,因为我收到一个错误(最大递归深度)。 I think renaming the methods of the attributes would solve this problem, but is this the best solution here? 我认为重命名属性的方法可以解决这个问题,但这是最好的解决方案吗?

Renaming all keys before the json.dumbs (see here ) is not a practical approach because I my class is more complex than the above example. 在json.dumbs之前重命名所有键(见这里 )并不是一个实用的方法,因为我的类比上面的例子更复杂。

So, what is the best practice to convert a Python object into JSON-format as fast as possible? 那么,尽可能快地将Python对象转换为JSON格式的最佳做法是什么?

If the example code you posted mirrors your real code, there really isn't any reason for the properties at all. 如果您发布的示例代码镜像您的实际代码,那么根本没有任何理由可以使用这些属性。 You could just do: 你可以这样做:

class User(object):
    def __init__(self):
        self.name = None
        self.age = None

since you're not really hiding anything from the user behind the underscores and properties anyway. 因为你并没有真正隐藏下划线和属性后面的用户的任何东西。

If you do need to do the transformation, I like to do it in a custom encoder: 如果您确实需要进行转换,我喜欢在自定义编码器中执行此操作:

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)

In Python, you'd normally not use properties for basic attributes. 在Python中,通常使用属性作为基本属性。 You'd leave name and age to be directly accessible attributes. 您可以将nameage保留为可直接访问的属性。 There is no need to wrap those in property objects unless you need to transform the data when getting or setting. 除非您在获取或设置时需要转换数据,否则无需将它们包装在property对象中。

If you have good reasons to use attributes with underscores but reflect them as JSON dictionaries, you can transform your dictionary when converting to a dictionary: 如果您有充分的理由使用带下划线的属性但将它们反映为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)

Note that this does nothing to prevent collisions. 请注意,这对防止冲突没有任何作用。 If you have both a _name and a name attribute on your instance, you'll clobber one or the other. 如果您的实例上同时具有_namename属性,那么您将破坏其中一个或另一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM