In the section titled What can be pickled and unpickled? of the Python documentation it indicates that only "classes that are defined at the top level of a module" can be pickled. However namedtuple()
is a factory function which is effectively defining a class (my_typename(tuple)
in your second example), however it's not assigning the manufactured type to a variable named my_typename
at the top level of the module.
This is because pickle
saves only the “fully qualified” name of such things, not their code, and they must be import
able from the module they're in using this name in order to be able to unpickled later (hence the requirement that the module must contain the named object at the top level).
This can be illustrated by seeing one workaround for the problem—which would be to change one line of the code so that the type named my_typename
is defined at the top level:
P = my_typename = namedtuple("my_typename", "A B C")
Alternatively, you could just give the namedtuple
the name "P"
instead of "my_typename"
:
P = namedtuple("P", "A B C")
As for what that namedtuple.py
source code you were looking at does: It's trying to determine the name of module the caller (the creator of the namedtuple
) is in because the author knows that pickle
might try to use it to import
the definition to do unpickling and that folks commonly assign the result to variable with the same name that they passed to the factory function (but you didn't in the second example).