Referencias en Python

Tengo una red de multidifusión que necesita enviar datos continuamente a todos los demás usuarios. Esta información cambiará constantemente, por lo que no quiero que el progtwigdor tenga que lidiar con el envío de paquetes a los usuarios. Debido a esto, estoy tratando de descubrir cómo puedo hacer una 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.

Aquí hay 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 esto sería muy apreciada.

ACTUALIZAR:

Lo he intentado de esta manera también:

 >>> 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 funcionó. 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!’ para ser ‘diferente’. en este caso. Estoy utilizando cadenas para pruebas y estoy acostumbrado a que las cadenas sean objetos de otros idiomas. Solo editaré el contenido dentro de un objeto, ¿así que esto terminará funcionando?

En Python, todo es una referencia, pero las cadenas no son mutables. Así que la test está sosteniendo una referencia a “prueba”. Si asigna “esto debería cambiar” para la test , simplemente cámbielo a otra referencia. Pero sus clientes todavía tienen la referencia a “prueba”. O más corto: ¡No funciona así en python! 😉

Una solución podría ser colocar los datos en un objeto:

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

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

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

No puedes, no fácilmente. Un nombre (variable) en Python es solo una ubicación para un puntero. Sobrescriba y simplemente reemplaza el puntero por otro puntero, es decir, el cambio solo es visible para las personas que usan la misma variable. Los miembros de los objetos son básicamente los mismos, pero como todos los que tienen un puntero los ven, se pueden propagar cambios como este. Solo tienes que usar para obj.var cada vez . Por supuesto, las cadenas (junto con los enteros, las tuplas, algunos otros tipos incorporados y otros tipos) son inmutables, es decir, no puede cambiar nada para que otros lo vean, ya que no puede cambiarlo en absoluto.

Sin embargo, la mutabilidad de los objetos abre otra posibilidad: podría , si se molestara en llevarlo a cabo, escribir una clase contenedora que contenga un objeto abritary, permita cambiar ese objeto a través del método set() y delegue todo lo importante a ese objeto. Sin embargo, probablemente te encontrarías con problemas de mal gusto tarde o temprano. Por ejemplo, no puedo imaginar que esto funcione bien con la metaprogtwigción que se realiza a través de todos los miembros, o cualquier cosa que piense que tiene que meterse. También es increíblemente hacky (es decir, poco confiable). Probablemente hay una solución mucho más fácil.

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