Python: использование `copyreg` для определения редукторов для типов, которые уже имеют редукторы - PullRequest
5 голосов
/ 29 мая 2010

(Имейте в виду, я работаю в Python 3, поэтому решение должно работать в Python 3.)

Я бы хотел использовать модуль copyreg, чтобы научить Python работать с функциями. Когда я пытался это сделать, объект _Pickler все равно пытался выбрать функции, используя функцию save_global. (Что не работает для несвязанных методов, и это мотивация для этого.)

Кажется, что _Pickler сначала пытается найти в своем собственном dispatch тип объекта, который вы хотите выбрать, прежде чем искать в copyreg.dispatch_table. Я не уверен, что это намеренно.

Можно ли как-нибудь сказать Python, что нужно выбирать функции с помощью предоставленного мной редуктора?

1 Ответ

1 голос
/ 29 мая 2010

Кажется, что следующий хак работает в Python 3.1 ...:

import copyreg
def functionpickler(f):
  print('pickling', f.__name__)
  return f.__name__

ft = type(functionpickler)
copyreg.pickle(ft, functionpickler)

import pickle
pickle.Pickler = pickle._Pickler
del pickle.Pickler.dispatch[ft]

s = pickle.dumps(functionpickler)
print('Result is', s)

Из этого две хакерские строки:

pickle.Pickler = pickle._Pickler
del pickle.Pickler.dispatch[ft]

Вам необходимо удалить запись dispatch для типа функций, потому что в противном случае она прерывает регистрацию copyreg; и я не думаю, что вы можете сделать это на C-кодированном Pickler, поэтому вам нужно установить его на Python-кодированный.

Было бы немного проще взломать подкласс _Pickler с вашим собственным классом, который создает свой собственный dispatch (копирование родительского элемента и удаление записи для типа функции), а затем специально использовать ваш подкласс (и его метод дампа), а не pickle.dump; однако было бы немного менее удобно, если бы эта маринованная маринада сама по себе мариновала.

...