2011-05-31 10 views
6

Tengo una red de multidifusión que necesita enviar continuamente datos a todos los demás usuarios. Esta información cambiará constantemente, por lo que no quiero que el programador tenga que encargarse del envío de paquetes a los usuarios. Debido a esto, estoy tratando de averiguar cómo puedo hacer referencia a cualquier objeto o variable en Python (soy nuevo en Python) para que el usuario pueda modificarlo y cambie lo que se envía en los paquetes de multidifusión.Referencias en Python

Aquí es un ejemplo de lo que quiero:

>>> test = "test" 
>>> mdc = MulticastDataClient() 
>>> mdc.add(test) # added into an internal list that is sent to all users 

# here we can see that we are successfully receiving the data 
>>> print mdc.receive() 
{'192.168.1.10_0': 'test'} 

# now we try to change the value of test 
>>> test = "this should change" 
>>> print mdc.receive() 
{'192.168.1.10_0': 'test'} # want 'test' to change to -> 'this should change' 

Cualquier ayuda sobre cómo puedo solucionar este problema sería muy apreciada.

ACTUALIZACIÓN:

He tratado de esta manera, así:

>>> test = [1, "test"] 
>>> mdc = MulticastDataClient() 
>>> mdc.add(test) 
>>> mdc.receive() 
{'192.168.1.10_1': 'test'} 
>>> test[1] = "change!" 
>>> mdc.receive() 
{'192.168.1.10_1': 'change!'} 

Esto ha funcionado. Sin embargo,

>>> val = "ftw!" 
>>> nextTest = [4, val] 
>>> mdc.add(nextTest) 
>>> mdc.receive() 
{'192.168.1.10_1': 'change!', '192.168.1.10_4': 'ftw!'} 
>>> val = "different." 
>>> mdc.receive() 
{'192.168.1.10_1': 'change!', '192.168.1.10_4': 'ftw!'} 

esto no funciona. ¡Necesito 'ftw!' convertirse en 'diferente' en este caso. Estoy usando cadenas para probar y estoy acostumbrado a que las cadenas sean objetos de otros idiomas. Solo editare el contenido dentro de un objeto asi que esto terminaria funcionando?

+0

¿Qué quiere decir con "Solo editare el contenido dentro de un objeto "? –

+0

@rshallit Entonces, si hay un objeto de posición llamado "pos", solo manipularía pos.x y pos.y, no tendría que preocuparse porque "pos" cambie su posición en la memoria. Supongo que fue redundante de mi parte publicar eso. –

Respuesta

5

En python todo es una referencia, pero las cadenas no son mutables. Entonces, test tiene una referencia a "prueba". Si asigna "esto debería cambiar" a test, simplemente cámbielo a otra referencia. Pero sus clientes todavía tienen la referencia a "prueba". O más corto: ¡no funciona de esa manera en Python! ;-)

Una solución podría ser la de poner los datos en un objeto:

data = {'someKey':"test"} 
mdc.add(data) 

Ahora sus clientes almacenar una referencia al diccionario. Si actualiza el diccionario de esta manera, sus clientes verán los cambios:

data['someKey'] = "this should change" 
+0

¿Estás seguro de que esto hará todo lo que él quiera? No estoy familiarizado con MulticastDataClient (si se trata de una clase/biblioteca real) pero, como mínimo, supongo que debe hacer algo para obligarlo a volver a enviar el paquete después del cambio – Foon

+0

Suponiendo que los datos traspasan los límites del proceso . En ese caso, tienes razón, pero para mí la pregunta implica que el póster original es consciente de eso. Creo que es bastante obvio que las referencias de Python no funcionan a través de sockets listos para usar. – Achim

+0

@Foon MulticastDataClient es algo que he creado. Está diseñado para controlar el envío de datos que el usuario local "posee" y multidifundir. Se deberán enviar todo tipo de datos utilizando objetos heredados MulticastDataClient. Entonces, un objeto puede manejar posiciones gps, otro puede manejar información del usuario, etc. En este momento, solo estoy usando cadenas para probar. Usé una implementación de lo que @Achim tiene arriba antes de hacer esta pregunta y he editado mi pregunta para mostrar lo que encontré al hacer esto. Gracias @Achim por reintegrarme en esta dirección. –

3

No puede, no es fácil. Un nombre (variable) en Python es solo una ubicación para un puntero. Sobrescríbelo y simplemente reemplace el puntero con otro puntero, es decir, el cambio solo es visible para las personas que usan la misma variable. Los miembros del objeto son básicamente los mismos, pero como su estado es visto por todos con un puntero hacia ellos, puede propagar cambios como este. Solo tiene que usar obj.varcada vez. Por supuesto, las cadenas (junto con enteros, tuplas, algunos otros tipos incorporados y muchos otros tipos) son inmutables, es decir, no puede cambiar nada para que otros puedan verlo, ya que no puede cambiarlo en absoluto.

Sin embargo, la mutabilidad de objetos se abre otra posibilidad: podía, si la molestia de pasar a través de, escribir una clase contenedora que contiene un objeto abritary, permite cambiar ese objeto a través de un set() método y delegados todo lo importante ese objeto Sin embargo, tarde o temprano te toparías con desagradables problemas. Por ejemplo, no puedo imaginar que esto funcione bien con la metaprogramación que atraviesa a todos los miembros, o cualquier cosa con la que piense que tiene que meterse. También es increíblemente hacky (es decir, no confiable). Existe una solución mucho más fácil.

(En una nota lateral, PyPy tiene una función become en uno de sus espacios de objetos no predeterminados que realmente y verdaderamente reemplaza un objeto por otro, visible para todos con referencia a ese objeto. No funciona con cualquier otra implementación, y creo que el increíble potencial y la confusión de uso incorrecto, así como el hecho de que la mayoría de nosotros casi nunca lo hemos necesitado, lo hace casi inaceptable en el código real.)