我编写了一个类,允许我将天数(整数)添加到日期(字符串 %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/