【问题标题】:json dumps with private fields带有私有字段的 json 转储
【发布时间】:2019-10-05 19:24:28
【问题描述】:

我想将用户序列化为 json。用户只有私有字段。

user.py

class User:
    def __init__(self, id, name):
        self. set_id(id)
        self.set_name(name)

    def set_id(self, id):
        self.__id = id

    def set_name(self, name):
        self.__name = name

json_encoder.py,没有它json.dumps 不起作用。

from json import JSONEncoder


class JsonEncoder(JSONEncoder):
    def default(self, o):
        return o.__dict__

user_app.py

import json
from json_encoder import JsonEncoder
from user import User

def main():
    users = build_users(names) # a function that returns list of users
    users_json = json.dumps(users, indent=4, sort_keys=True, cls=JsonEncoder)
    print(users_json)


if __name__ == '__main__':
    main()

打印出来

[
    {
        "_User__id": 0,
        "_User__name": "Alex"
    },
    {
        "_User__id": 1,
        "_User__name": "John"
    }
]

这几乎是好的。但是,我希望将私有字段作为字段名 - 没有类名前缀。

[
    {
        "id": 0,
        "name": "Alex"
    }
]

是否有注解,或者我应该写自定义助手来自定义json输出。

顺便问一下,在python中创建私有字段是一种好习惯吗?我来自 Java 世界,我们确实更喜欢私有字段。

更新

How to make a class JSON serializable 部分回答了我的问题。如何用漂亮的属性名称对其进行序列化,请参阅我的输出示例,我仍然需要了解更多信息。我不知道如何自定义 JsonEncoder。我发布了我的答案。

【问题讨论】:

  • 既然已经有了自定义编码器,为什么不把自定义字段名放在那里呢?
  • 您必须编写一个自定义 JSONEncoder - _User__id 是属性的 实际名称,名称修饰是 Python 实现隐私的方式。请注意,使用 setter/getter 并不是特别 Pythonic,只需直接访问属性即可。 (如果您确实需要在 set/get 上执行代码,您可以在事后通过 @property 添加。)
  • @rdas 怎么放自定义字段名?
  • 不是返回o.__dict__,而是从idnameo构建字典。你需要 idname 的吸气剂

标签: json python-3.x


【解决方案1】:

感谢jasonharper 到目前为止,我找到了example about properties and setters 现在我知道如何在python中进行封装了。

user.py

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

接下来,我需要serialize it into JSON

json_encoder.py

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()}

现在输出对我来说是正确的。

[
    {
        "id": 0,
        "name": "Alex"
    },
    {
        "id": 1,
        "name": "John"
    }
]

【讨论】:

    猜你喜欢
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 2013-03-08
    • 2020-12-19
    • 1970-01-01
    相关资源
    最近更新 更多