2009-11-25 10 views
8

Parece que Python tiene algunas limitaciones con respecto a los métodos de instancia.Superar las limitaciones de Python con respecto a los métodos de instancia

  1. Los métodos de instancia no se pueden copiar.
  2. Los métodos de instancia no se pueden conservar en escabeche.

Esto es problemático para mí, porque yo trabajo en un project en la que me refiero a los métodos de instancia, y no hay uso de ambos deepcopying y decapado orientado a objetos muy. El decapado se realiza principalmente por el mecanismo de multiprocesamiento.

¿Cuál sería una buena manera de resolver esto? Hice una solución fea para el problema de la copia, pero Estoy buscando una solución más adecuada para ambos problemas.

¿Alguien tiene alguna sugerencia?

Actualización:

Mi caso de uso: Tengo un sistema de eventos de pequeña. Cada evento tiene un atributo .action que apunta a una función que se supone que debe desencadenar, y en ocasiones esa función es un método de instancia de algún objeto.

+5

Normalmente proporcionamos el código en todas las ubicaciones en las que estamos trabajando y simplemente movemos una representación del estado. Representación State Transfer es más común y más simple. ¿Qué está mal con eso? –

+0

S.Lott, claramente tiene más experiencia con este tema, pero por favor explíqueme de una manera más simplificada, qué está sugiriendo exactamente, cómo se relaciona, qué es "Transferencia de estado de representación", etc. –

+0

Estás diciendo "Quiero escanear métodos de instancia", pero no estás diciendo por qué. Nos ayudaría a saber qué problema está tratando de resolver, ya que puede haber una forma más pitonica de hacerlo. Suena un poco como si estuvieras pensando en Ruby ... –

Respuesta

15

Usted puede ser capaz de hacer esto utilizando copy_reg.pickle. En Python 2.6:

import copy_reg 
import types 

def reduce_method(m): 
    return (getattr, (m.__self__, m.__func__.__name__)) 

copy_reg.pickle(types.MethodType, reduce_method) 

Esto no almacena el código del método, sólo su nombre; pero eso funcionará correctamente en el caso común.

¡Esto hace que tanto el decapado como el copiado funcionen!

+0

Buena idea, creo que podría ser la solución más limpia. ¿Tienes alguna idea para el otro problema, copiar? Además, ¿alguien ya implementó una solución 'copy_reg' que puedo usar? –

+0

Edité la respuesta y agregué un código. –

3

REST - Representation State Transfer. Simplemente envíe el estado, no los métodos.

Para transferir un objeto X de A a B, hacemos esto.

  1. A codificar el estado de X en algunos notación práctico, fácil de análisis sintáctico. JSON es popular.

  2. A envía el texto JSON a B.

  3. B decodifica el estado de forma X JSON notación, la reconstrucción de X.

B debe tener las definiciones de clase para la clase de X para este trabajar. B debe tener todas las funciones y otras definiciones de clases de las que depende la clase X. En resumen, tanto A como B tienen todas las definiciones. Solo se mueve una representación del estado del objeto .

Vea cualquier artículo sobre REST.

http://en.wikipedia.org/wiki/Representational_State_Transfer

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

+0

¿Puede explicar cómo se relaciona esta metodología con mi problema con el sistema de eventos? –

+4

Esta es una respuesta de "lo estás haciendo mal". Esta visión es que 'pickle' es quizás un poco * demasiado * conveniente en Python; es realmente mejor intercambiar datos antiguos simples (a diferencia de los gráficos de objetos) porque da como resultado sistemas más simples que son más sensatos. Hay algo de eso, pero si es útil para ti, será útil a largo plazo. –

-3

pickle la instancia y luego acceder el método después de deserialiación ella. El decapado de un método de una instancia no tiene sentido porque depende de la instancia. Si no es así, escríbalo como una función independiente.

import pickle 

class A: 
    def f(self): 
     print 'hi' 

x = A() 
f = open('tmp', 'w') 
r = pickle.dump(x, f) 
f.close() 
f = open('tmp', 'r') 
pickled_x = pickle.load(f) 
pickled_x.f() 
+1

A() no es un método de instancia. –

+1

Has decapado el objeto, no el método de instancia. Intente develar un método de instancia directamente. –

+0

salmuera la instancia y luego acceda al método después de desatornillarlo. Degradar un método de una instancia no tiene sentido porque se basa en la instancia. Si no es así, escríbalo como una función independiente. –

Cuestiones relacionadas