Python 3.9: unpickling IsoCalendarDate 数据 returns 一个元组
Python 3.9: unpickling of IsoCalendarDate data returns a tuple
考虑 Python3.9 中的以下讨论/功能:
https://bugs.python.org/issue24416
简而言之,决定将 datetime.date.isocalendar
的结果改为 namedtuple
而不是 tuple
。
现在,我可以看到这样做的好处,但他们还决定将新对象 (datetime.IsoCalendarDate
)“腌制”为元组:
https://github.com/python/cpython/commit/1b97b9b0ad9a2ff8eb5c8f2e2e7c2aec1d13a330#diff-2a8962dcecb109859cedd81ddc5729bea57d156e0947cb8413f99781a0860fd1R1214
所以我的问题是,为什么他们要直接创建对象,而“pickling-and-unpickling”对象需要稍微不同的流程?
例如:
import datetime
from pathlib import Path
import pickle
RESULTS_CACHE_PICKLE = Path('cache.pickle')
if RESULTS_CACHE_PICKLE.is_file():
with open(RESULTS_CACHE_PICKLE, 'rb') as f:
icd = pickle.load(f)
else:
icd = datetime.date(2019, 1, 1).isocalendar()
with open(RESULTS_CACHE_PICKLE, 'wb') as f:
pickle.dump(icd, f)
print(icd.year)
结果:
$ python icd_test.py
2019
$ python icd_test.py
Traceback (most recent call last):
File "icd_test.py", line 19, in <module>
print(icd.year)
AttributeError: 'tuple' object has no attribute 'year'
这种不一致对我来说看起来不稳定。它是否发生在语言的其他地方?
我猜,正如 蝙蝠侠 在 中评论的建议:
One is that namedtuple
isn't a class, it's a class factory that
returns a class, which you in turn use to make instances. (...)
不幸的是,正如我们在 IsoCalendarDate(tuple)
class:
的代码中所读到的那样(故意的!)
def __reduce__(self):
# This code is intended to pickle the object without making the
# class public. See https://bugs.python.org/msg352381
return (tuple, (tuple(self),))
所以看来,对于 some reason,这种无关紧要的方法是故意采取的,但我不知道 Python 代码中有 (m) 任何类似情况。
我认为您可以将其作为错误提出。也许应该重新审视从 pickle
的角度保持 IsoCalendarDate
私有的理由。
考虑 Python3.9 中的以下讨论/功能: https://bugs.python.org/issue24416
简而言之,决定将 datetime.date.isocalendar
的结果改为 namedtuple
而不是 tuple
。
现在,我可以看到这样做的好处,但他们还决定将新对象 (datetime.IsoCalendarDate
)“腌制”为元组:
https://github.com/python/cpython/commit/1b97b9b0ad9a2ff8eb5c8f2e2e7c2aec1d13a330#diff-2a8962dcecb109859cedd81ddc5729bea57d156e0947cb8413f99781a0860fd1R1214
所以我的问题是,为什么他们要直接创建对象,而“pickling-and-unpickling”对象需要稍微不同的流程?
例如:
import datetime
from pathlib import Path
import pickle
RESULTS_CACHE_PICKLE = Path('cache.pickle')
if RESULTS_CACHE_PICKLE.is_file():
with open(RESULTS_CACHE_PICKLE, 'rb') as f:
icd = pickle.load(f)
else:
icd = datetime.date(2019, 1, 1).isocalendar()
with open(RESULTS_CACHE_PICKLE, 'wb') as f:
pickle.dump(icd, f)
print(icd.year)
结果:
$ python icd_test.py
2019
$ python icd_test.py
Traceback (most recent call last):
File "icd_test.py", line 19, in <module>
print(icd.year)
AttributeError: 'tuple' object has no attribute 'year'
这种不一致对我来说看起来不稳定。它是否发生在语言的其他地方?
我猜,正如 蝙蝠侠 在
One is that
namedtuple
isn't a class, it's a class factory that returns a class, which you in turn use to make instances. (...)
不幸的是,正如我们在 IsoCalendarDate(tuple)
class:
def __reduce__(self):
# This code is intended to pickle the object without making the
# class public. See https://bugs.python.org/msg352381
return (tuple, (tuple(self),))
所以看来,对于 some reason,这种无关紧要的方法是故意采取的,但我不知道 Python 代码中有 (m) 任何类似情况。
我认为您可以将其作为错误提出。也许应该重新审视从 pickle
的角度保持 IsoCalendarDate
私有的理由。