Pickle не работает для класса, унаследованного от "namedtuple" при переопределении "__new__" - PullRequest
0 голосов
/ 20 июня 2019

Сбой следующего кода

from collections import namedtuple
import pickle

class Foo(namedtuple("_Foo", ["a", "b"])):
    def __new__(cls, **kwargs):
        self = super().__new__(cls, **kwargs)
        # some custom code
        return self

foo = Foo(a=1, b=2)
pickle.loads(pickle.dumps(foo))

с

Traceback (most recent call last):
  File "bar.py", line 10, in <module>
    pickle.loads(pickle.dumps(foo))
TypeError: __new__() takes 1 positional argument but 3 were given

Это работает, если я удаляю новую реализацию __new__, но я хочу, чтобы там был какой-то собственный код. Как мне нужно изменить реализацию __new__, чтобы не было ошибки?

Я использую Python 3.5.

1 Ответ

2 голосов
/ 20 июня 2019

Причина довольно проста;в общем, C API передает вещи как позиционные параметры, а не именованные параметры.Поэтому вам просто нужно указать для этого *args:

from collections import namedtuple
import pickle

class Foo(namedtuple("_Foo", ["a", "b"])):
    def __new__(cls, *args, **kwargs):
        self = super().__new__(cls, *args, **kwargs)
        # some custom code
        return self

foo = Foo(a=1, b=2)
pickle.loads(pickle.dumps(foo))
...