2010-05-28 9 views
9

Me gustaría seleccionar un método independiente en Python 3.x. Obtengo este error:Decapado de un método independiente en Python 3

>>> class A: 
...  def m(self): 
...   pass 
>>> import pickle 
>>> pickle.dumps(A.m) 
Traceback (most recent call last): 
    File "<pyshell#3>", line 1, in <module> 
    pickle.dumps(A.m) 
    File "C:\Python31\lib\pickle.py", line 1358, in dumps 
    Pickler(f, protocol, fix_imports=fix_imports).dump(obj) 
_pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed 

¿Alguien tiene experiencia con esto?


Nota: En Python 2.x también es imposible eliminar los métodos de unión por defecto; Me las arreglé para hacerlo allí de una manera extraña que no entiendo: escribí un reductor con el módulo copy_reg para la clase MethodType, que abarca los métodos vinculados y no vinculados. Pero el reductor solo resolvió el caso del método vinculado, porque dependía de my_method.im_self. Misteriosamente, también ha provocado que Python 2.x pueda extraer métodos independientes. Esto no ocurre en Python 3.x.

Respuesta

7

Esto no se puede hacer directamente porque en Python 3 no unido tipo de método se ha ido: es sólo una función:

>>> print (type (A.m)) 
<class 'function'> 

funciones de Python no están vinculados a una clase, por lo que es imposible decir qué clase A.m pertenece simplemente al mirar el resultado de la expresión.

Dependiendo de qué es exactamente lo que necesita, decapado/deserialiación una tupla de (clase, nombre del método) podría ser lo suficientemente bueno:

>>> print (pickle.loads (pickle.dumps ((A, 'm')))) 
... (<class '__main__.A'>, 'm') 

, usted puede obtener el método (función) de aquí simplemente usando getattr() :

>>> cls, method = pickle.loads (pickle.dumps ((A, 'm'))) 
>>> print (getattr (cls, method)) 
... <function m at 0xb78878ec> 
+1

¿Está diciendo que en Python 3, dado un método independiente, no hay forma de saber dónde se definió ese método? –

+4

Sí. Intente declarar dos clases y asigne un método de uno a otro ('B.m = A.m'). Entonces 'B.m' y' A.m' serán iguales (de hecho, idénticos), por lo que no es posible determinar si buscó el método en 'B' o en' A'. – doublep

Cuestiones relacionadas