Python 3.9: pembongkaran data IsoCalendarDate mengembalikan tupel

Oct 17 2020

Pertimbangkan diskusi / fitur berikut di Python3.9: https://bugs.python.org/issue24416

Singkatnya, diputuskan bahwa hasil datetime.date.isocalendarakan berubah menjadi namedtuplebukan tuple.

Sekarang, saya dapat melihat manfaat dari melakukan itu, tetapi mereka juga memutuskan "untuk membuat acar" objek baru ( datetime.IsoCalendarDate) sebagai tupel:
https://github.com/python/cpython/commit/1b97b9b0ad9a2ff8eb5c8f2e2e7c2aec1d13a330#diff-2a8962dcecb109859cedd81ddc5729bea57d156e0947cb8413f99781a0860fd1R1214

Jadi pertanyaan saya adalah, mengapa mereka membuatnya sehingga membuat objek secara langsung, dan "mengawetkan-dan-membongkar" objek memerlukan aliran yang sedikit berbeda?

Sebagai contoh:

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)

Hasil dalam:

$ 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'

Ketidakkonsistenan ini terlihat tidak stabil bagi saya. Apakah itu terjadi di tempat lain dalam bahasa tersebut?

Jawaban

1 sophros Oct 18 2020 at 08:47

Saya kira, seperti yang disarankan oleh komentar Batman dalam jawaban ini :

Salah satunya adalah itu namedtuplebukan kelas, itu adalah pabrik kelas yang mengembalikan kelas, yang pada gilirannya Anda gunakan untuk membuat instance. (...)

Dan sayangnya, ini adalah kasusnya (sengaja!) Seperti yang dapat kita baca di kode IsoCalendarDate(tuple)kelas:

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),))

Jadi tampaknya, untuk beberapa alasan , pendekatan tidak penting diambil dengan sengaja tetapi saya tidak mengetahui (m) situasi serupa dalam kode Python.

Saya pikir Anda bisa membesarkannya sebagai bug. Mungkin alasan untuk merahasiakan IsoCalendarDatedari pickleperspektif harus ditinjau kembali.