8

I have a multicasting network that needs to continuously send data to all other users. This data will be changing constantly so I do not want the programmer to have to deal with the sending of packets to users. Because of this, I am trying to find out how I can make a reference to any object or variable in Python (I am new to Python) so it can be modified by the user and changes what is sent in the multicasting packets.

Here is an example of what I want:

>>> 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'

Any help on how I can fix this would be very much appreciated.

UPDATE:

I have tried it this way as well:

>>> 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!'}

This did work. However,

>>> 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!'}

This does not work. I need 'ftw!' to become 'different.' in this case. I am using strings for testing and am used to strings being objects from other languages. I will only be editing the contents inside of an object so would this end up working?

2
  • What do you mean by "I will only be editing the contents inside of an object"? Commented May 31, 2011 at 20:52
  • @rshallit So if there we a position object called "pos", I would only manipulate pos.x and pos.y, you wouldn't have to worry about "pos" changing its position in memory. I guess it was redundant of me to post that. Commented May 31, 2011 at 23:45

2 Answers 2

5

In python everything is a reference, but strings are not mutable. So test is holding a reference to "test". If you assign "this should change" to test you just change it to another reference. But your clients still have the reference to "test". Or shorter: It does not work that way in python! ;-)

A solution might be to put the data into an object:

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

Now your clients hold a reference to the dictionary. If you update the dictionary like this, your clients will see the changes:

data['someKey'] = "this should change"
Sign up to request clarification or add additional context in comments.

4 Comments

Are you sure this will do all of what he wants? I'm not familiar with MulticastDataClient (if it's an actual class/library) but at a minimum, I assume you'd have to do something to force it to resend the packet after the change
You assume that the data goes across process boundaries. In that case you're right, but to me the question implies that the original poster is aware of that. I thinks it's quite obivious that python references do not work through sockets out of the box.
@Foon MulticastDataClient is something that I have created. It is meant to control sending data that the local user "owns" and multicast it. All kinds of data will need to be sent using inherited MulticastDataClient objects. So one object may handle gps positions, another may handle user information, etc. Right now, I'm just using strings to test with. I used an implementation of what @Achim has above before asking this question and have edited my question to show what I came across doing this. Thank you @Achim for repointing me back in this direction.
Primitive types are not refferences.
4

You can't, not easily. A name (variable) in Python is just a location for a pointer. Overwrite it and you just replace the pointer with another pointer, i.e. the change is only visible to people who use the same variable. Object members are basically the same, but as their state is seen by everyone with a pointer to them, you can propagate changes like this. You just have to use obj.var every single time. Of course, strings (along with integers, tuples, a few other built-in types, and several other types) are immutable, i.e. you can't change anything about for others to see as you can't change it at all.

However, the mutability of objects opens another possibility: You could, if you bothered to pull it through, write a wrapper class that contains an arbitrary object, allows changing that object though a set() method and delegates everything important to that object. You'd probably run into nasty little troubles sooner or later though. For example, I can't imagine this would play well with metaprogramming that goes through all members, or anything that thinks it has to mess with. It's also incredibly hacky (i.e. unreliable). There's probably a much easier solution.

(On a side note, PyPy has a become function in one of its non-default object spaces that really and truly replaces one object with another, visible to everyone with a reference to that object. It doesn't work with any other implementations though and I think the incredible potential and misuse confusion as well as the fact most of us have rarely ever needed this makes it nearly unacceptable in real code.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.