Python3.5 对象和 json.dumps() 输出

标签 python json class datetime python-3.5

我编写了一个类,允许我将天数(整数)添加到日期(字符串 %Y-%m-%d)。此类的对象需要是 JSON 可序列化的。

以整数形式向我的对象添加天数按预期工作。但是 json.dumps(obj) 为我的原始对象返回了太多信息(“2016-03-23 15:57:47.926362”)。 为什么?我需要如何修改类才能改为获取“"2016-03-23"?请参见下面的示例。

代码:

from datetime import datetime, timedelta
import json

class Day(str):
    def __init__(self, _datetime):
        self.day = _datetime

    def __str__(self):
        return self.day.date().isoformat()

    def __repr__(self):
        return "%s" % self.day.date().isoformat()

    def __add__(self, day):
        new_day = self.day + timedelta(days=day)
        return Day(new_day).__str__()

    def __sub__(self, day):
        new_day = self.day - timedelta(days=day)
        return Day(new_day).__str__()


if __name__ == "__main__":
    today = Day(datetime.today())
    print(today)               # 2016-03-23
    print(json.dumps(today))   # "2016-03-23 15:57:47.926362"
    print(today+1)             # 2016-03-24
    print(json.dumps(today+1)) # "2016-03-24"
    print(today-1)             # 2016-03-22
    print(json.dumps(today-1)) # "2016-03-22"

更新。对于那些感兴趣的人,这是我的最终代码:

from datetime import datetime, timedelta
import json


class Day(str):
    def __init__(self, datetime_obj):
        self.day = datetime_obj

    def __new__(self, datetime):
        return str.__new__(Day, datetime.date().isoformat())

    def __add__(self, day):
        new_day = self.day + timedelta(days=day)
        return Day(new_day)

    def __sub__(self, day):
        new_day = self.day - timedelta(days=day)
        return Day(new_day)


if __name__ == "__main__":
    today = Day(datetime.today())
    print(type(today))
    print(today)  # 2016-03-23
    print(json.dumps(today))  # "2016-03-23"
    print(today + 1)  # 2016-03-24
    print(json.dumps(today + 1))  # "2016-03-24"
    print(today - 1)  # 2016-03-22
    print(json.dumps(today - 1))  # "2016-03-22"
    print(json.dumps(dict(today=today))) # {"today": "2016-03-23"}
    print(json.dumps(dict(next_year=today+365))) # {"next_year": "2017-03-23"}
    print(json.dumps(dict(last_year=today-366))) # {"last_year": "2015-03-23"}

最佳答案

太棒了!让我们一起去吧。您正在看到:

print(json.dumps(today))   # "2016-03-23 15:57:47.926362"

因为 somewhere在编码过程中,当决定如何序列化传递给它的内容时,json.dumps 调用对象上的 isinstance(..., str)。这将返回 True 并且您的对象被序列化为 secret 的字符串。

但是 "2016-03-23 15:57:47.926362" 值从何而来?

当您调用 day = Day(datetime_obj) 时,会发生两件事:

  • __new__ is called 实例化对象。您尚未提供 __new__ 方法,因此使用了 str.__new__
  • __init__ 被调用以初始化对象。

因此 day = Day(datetime_obj) 有效地转换为:

day = str.__new__(Day, datetime_obj)

对于 json.dumps,您的对象将是一个 str,但 str 的值设置为默认的字符串表示形式日期时间对象。这恰好是您看到的完整格式。内置,伙计!

我玩过这个,似乎如果你推出自己的 __new__ (这是一个有点令人兴奋的领域,小心行事)拦截 str.__new__ 调用,你~~应该~~很好:

class Day(str):
    def __new__(self, datetime):
        return str.__new__(Day, datetime.date().isoformat())

但是如果整件事都着火了,你没有听到我的消息。

PS 正确的做法would be子类 JSONEncoder。但它的乐趣为零。

PS2 哦,糟糕,我在 2.7 上测试过这个。我可能完全不在那里,如果是,请给我一个 "you tried"徽章。

关于Python3.5 对象和 json.dumps() 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36181844/

相关文章:

python - 裁剪 numpy 图像的中心部分

json - 在centos上安装perl-JSON

android - 如何使用 GSON 解析 JSON,以获取 JSONObject 未按需要解析的错误 JSON?

java - 为什么变量打印不正确?

jQuery 选择带有 ID 和类的 div

python - numpy 数组的矢量化 "by-layer"缩放

Python - 和,或验证

python - 在 Python 3.x 中保留或添加小数位

javascript - 如何对数组等对象列表进行排序

两个对象组合的Python属性