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

Jak*_*cki 2 python datetime json class 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"
Run Code Online (Sandbox Code Playgroud)

更新。这是我为感兴趣的人提供的最终代码:

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"}
Run Code Online (Sandbox Code Playgroud)

mal*_*ree 5

凉爽的!让我们一起去吧。你看到的是:

print(json.dumps(today))   # "2016-03-23 15:57:47.926362"
Run Code Online (Sandbox Code Playgroud)

因为在编码过程的某个地方,在决定如何序列化传递给它的内容时,会json.dumps调用isinstance(..., str)您的对象。这将返回True并且您的对象被序列化,就像它秘密的字符串一样。

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

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

  • __new__ 被调用实例化对象。你还没有提供__new__方法,所以str.__new__使用了。
  • __init__被调用来初始化对象。

所以day = Day(datetime_obj)有效地转化为:

day = str.__new__(Day, datetime_obj)
Run Code Online (Sandbox Code Playgroud)

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

我玩弄了这个,似乎如果你自己滚动__new__(这是一个稍微令人兴奋的领域,小心行事)拦截str.__new__呼叫,你~~应该~~没问题:

class Day(str):
    def __new__(self, datetime):
        return str.__new__(Day, datetime.date().isoformat())
Run Code Online (Sandbox Code Playgroud)

但如果整件事着火了,你没有从我这里听到。

PS正确的方法JSONEncoder. 但它的乐趣为零。

PS2哦,射击,我在2.7. 我可能完全不在那里,如果我是,请给我一个“您尝试过”的徽章。