Python 为什么可以';我不能pickle一个typing.NamedTuple而我可以pickle一个collections.NamedTuple吗?

Python 为什么可以';我不能pickle一个typing.NamedTuple而我可以pickle一个collections.NamedTuple吗?,python,pickle,namedtuple,python-3.5,Python,Pickle,Namedtuple,Python 3.5,为什么我不能pickle atyping.NamedTuple,而我可以pickle acollections.NamedTuple?如何处理pickle aNamedTuple 这段代码显示了我迄今为止所做的尝试: from collections import namedtuple from typing import NamedTuple PersonTyping = NamedTuple('PersonTyping', [('firstname',str),('lastname',st

为什么我不能pickle a
typing.NamedTuple
,而我可以pickle a
collections.NamedTuple
?如何处理pickle a
NamedTuple

这段代码显示了我迄今为止所做的尝试:

from collections import namedtuple
from typing import NamedTuple

PersonTyping = NamedTuple('PersonTyping', [('firstname',str),('lastname',str)])
PersonCollections = namedtuple('PersonCollections', ['firstname','lastname'])

pt = PersonTyping("John","Smith")
pc = PersonCollections("John","Smith")


import pickle
import traceback

try:
    with open('personTyping.pkl', 'wb') as f:
        pickle.dump(pt, f)
except:
    traceback.print_exc()
try:
    with open('personCollections.pkl', 'wb') as f:
        pickle.dump(pc, f)
except:
    traceback.print_exc()
外壳上的输出:

$ python3 prova.py 
Traceback (most recent call last):
  File "prova.py", line 16, in <module>
    pickle.dump(pt, f)
_pickle.PicklingError: Can't pickle <class 'typing.PersonTyping'>: attribute lookup PersonTyping on typing failed
$ 
$python3 prova.py
回溯(最近一次呼叫最后一次):
文件“prova.py”,第16行,在
腌制垃圾场(pt,f)
_pickle.PicklingError:无法pickle:键入时属性查找PersonTyping失败
$ 

这是一个bug。我在上面开了一张票:

问题在于,函数在创建类时,通过从调用帧的全局中查找
\uuuuu name\uuuuu
属性来设置其
\uuuuu模块
属性。在这种情况下,调用方是
键入.NamedTuple

result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
因此,在本例中,它最终将其设置为“键入”

>>> type(pt)
<class 'typing.PersonTyping'>  # this should be __main__.PersonTyping
>>> type(pc)
<class '__main__.PersonCollections'>
>>> import typing
>>> typing.NamedTuple.__globals__['__name__']
'typing'

目前,您还可以执行以下操作:

PersonTyping = NamedTuple('PersonTyping', [('firstname',str),('lastname',str)])
PersonTyping.__module__ = __name__

您的两个修复工作,非常感谢!另外,感谢您的解释和已经提交的补丁!如果触发了
AttributeError
ValueError
,则生成的NamedTuple仍然不可拾取,对吗?您应该提到这一点。这已在
python 3.5.1
中修复。
PersonTyping = NamedTuple('PersonTyping', [('firstname',str),('lastname',str)])
PersonTyping.__module__ = __name__