2011-05-31 807 views
6

我有一個多播網絡,需要連續發送數據給所有其他用戶。這些數據會不斷變化,所以我不希望程序員必須處理向用戶發送數據包。因此,我試圖找出如何在Python中引用任何對象或變量(我是Python的新手),以便用戶可以修改它並更改多播包中發送的內容。Python中的參考文獻

這裏是我想要的一個例子:

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

我如何能解決這個問題的任何幫助將是非常讚賞。

UPDATE:

我也這樣嘗試過,以及:

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

該做的工作。 但是,

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

這是行不通的。我需要'ftw!'變得「不同」。在這種情況下。 我正在使用字符串進行測試,並使用字符串作爲來自其他語言的對象。我只會編輯對象內部的內容,這樣最終會起作用嗎?

+0

你是什麼意思「我只會編輯對象內的內容「? – 2011-05-31 20:52:45

+0

@rshallit所以如果我們有一個名爲「pos」的位置對象,我只能操作pos.x和pos.y,您不必擔心「pos」在內存中改變其位置。我想這對我來說是多餘的。 – 2011-05-31 23:45:25

回答

5

在python中,一切都是引用,但字符串不可變。所以test持有對「測試」的引用。如果您將「這應該更改」分配給test,您只需將其更改爲另一個參考。但您的客戶仍然有「測試」的參考。或者更短:它在python中不能這麼做! ;-)

一個解決辦法可能是把數據放到一個對象:

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

現在你的客戶持有的參考字典。如果您更新字典這樣,您的客戶將看到變化:

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

你確定這會做所有他想要的嗎?我不熟悉MulticastDataClient(如果它是一個實際的類/庫),但至少我假設你必須做一些事情來迫使它在改變之後重新發送數據包 – Foon 2011-05-31 19:36:38

+0

你假定數據跨過進程邊界。在這種情況下,你是對的,但對我來說,這個問題意味着原始的海報意識到這一點。我認爲這很明顯,python引用不能通過套接字工作。 – Achim 2011-05-31 19:38:52

+0

@Fun MulticastDataClient是我創建的東西。它旨在控制發送本地用戶「擁有」並多播它的數據。需要使用繼承的MulticastDataClient對象發送各種數據。所以一個對象可以處理GPS位置,另一個可以處理用戶信息等。現在,我只是使用字符串來測試。 在提出這個問題之前,我使用了@Achim的一個實現,並且編輯了我的問題以顯示我遇到的問題。謝謝@Achim讓我回到這個方向。 – 2011-05-31 20:08:17

3

你不能,不容易。 Python中的名稱(變量)只是指針的位置。覆蓋它,你只需用另一個指針替換指針,即只有使用相同變量的人才能看到更改。對象成員基本上是相同的,但是由於每個人都可以看到他們的狀態,並且有指向他們的指針,所以可以像這樣傳播更改。你只需要使用obj.var每一次。當然,字符串(連同整數,元組,其他幾種內置類型和其他幾種類型)是不可變的,即你不能改變任何關於其他類型的東西,因爲你根本無法改變它。

然而,對象的可變性打開另一個可能性:你可能,如果你不屑把它拉過,寫一個包含abritary對象的包裝類,允許改變該對象雖然set()方法和代表一切重要那個對象。儘管如此,你早晚會遇到棘手的小問題。例如,我無法想象這種方式會適用於所有成員的元編程,或任何認爲它必須混淆的元編程。它也非常不可靠(即不可靠)。有一個更簡單的解決方案。(在附註中,PyPy在其中一個非默認對象空間中有一個become函數,它真正地真正地將一個對象替換爲另一個對象,每個人都可以通過引用該對象來看到它。任何其他的實現,但我認爲難以置信的潛力和誤用的困惑以及我們大多數人很少需要這樣的事實使得它在真實代碼中幾乎不可接受。)