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)
凉爽的!让我们一起去吧。你看到的是:
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. 我可能完全不在那里,如果我是,请给我一个“您尝试过”的徽章。