[Python-Dev] Unbinding of methods

Richard Oudkerk shibturn at gmail.com
Thu Jul 19 21:51:39 CEST 2012


On 19/07/2012 7:54pm, Antoine Pitrou wrote:
 > Instead of a specific opcode, can't you use a suitable __reduce__
 > magic (or __getnewargs__, perhaps)? We want to limit the number of
 > opcodes except for performance-critical types (and I don't think
 > bound methods are performance-critical for the purpose of
 > serialization).
The one wrinkle is that BuiltinFunctionType is special cased to be 
pickled with save_global, and has no fallback to 
__reduce__/__reduce_ex__/copyreg. (The C implementation for 
FunctionType *does* have such a fallback, whereas the Python 
implementation doesn't -- see bug http://bugs.python.org/issue14336.)
If the fallback is added for BuiltinFunctionType then "__reduce__ magic" 
should be enough.
The following code works as expected:
import pickle
import copyreg
class A(object):
 def f(self):
 pass
 @classmethod
 def g(cls):
 pass
def f(self):
 pass
ClassMethodDescriptorType = type(A.g)
BuiltinFunctionType = type(len)
FunctionType = type(f)
MethodType = type(A().f)
MethodDescriptorType = type(list.append)
WrapperDescriptorType = type(list.__add__)
MethodWrapperType = type([].__add__)
obj_list = [A.g, len, f, A().f, list.append, list.__add__, [].__add__]
assert ClassMethodDescriptorType is MethodType
def reduce_self(self):
 return getattr, (self.__self__, self.__name__)
def reduce_objclass(self):
 return getattr, (self.__objclass__, self.__name__)
copyreg.pickle(MethodType, reduce_self)
copyreg.pickle(BuiltinFunctionType, reduce_self)
copyreg.pickle(MethodWrapperType, reduce_self)
copyreg.pickle(MethodDescriptorType, reduce_objclass)
copyreg.pickle(WrapperDescriptorType, reduce_objclass)
for obj in obj_list:
 data = pickle.dumps(obj)
 new_obj = pickle.loads(data)
 print('%s\n%s\n' % (obj, new_obj))


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /