Python 3.9:取消选择IsoCalendarDate数据将返回一个元组

问题描述

请考虑以下python3.9中的讨论/功能https://bugs.python.org/issue24416

简而言之,决定将datetime.date.isocalendar的结果更改为namedtuple而不是tuple

现在,我可以看到这样做的好处,但他们还决定将新对象(datetime.IsoCalendarDate)作为元组“腌制”:
https://github.com/python/cpython/commit/1b97b9b0ad9a2ff8eb5c8f2e2e7c2aec1d13a330#diff-2a8962dcecb109859cedd81ddc5729bea57d156e0947cb8413f99781a0860fd1R1214

所以我的问题是,为什么要这样做,以便直接创建对象以及“酸洗和取消酸洗”对象需要略有不同的流程?

例如:

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'

这种不一致在我看来不稳定。它会在该语言的其他地方发生吗?

解决方法

我猜,正如this answer中的 Batman 评论所建议的那样:

一个是namedtuple不是课程,是课程工厂 返回一个类,您依次使用该类来创建实例。 (...)

不幸的是,正是这种情况(故意!),正如我们可以在IsoCalendarDate(tuple)类的代码中看到的一样:

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)种类似情况。

我认为您可以将其作为错误提出。也许应该重新审视从IsoCalendarDate角度来看pickle不公开的理由。