2015-09-02 59 views
0
def is_safe(self,requesting_train_name,requesting_train_priority,requested_resources): 
    # Initialize P1 & P0 
    # We need to maintain an AR. 
    performer = requesting_train_name 
    AR = set(filter(lambda x : G.node[x]['reservation'] <= requesting_train_priority, G.nodes())) 
    P1 = [] 
    P0 = self.active_trains.keys() 

    active_trains_trial = self.active_trains.copy() 
    print active_trains_trial is self.active_trains 

    # Update AR. Remove all elements of requested resources from AR 
    AR.difference_update(set(requested_resources)) 

    # Provisionally updating OR 
    print 'OR before update',self.active_trains[performer].OR 
    active_trains_trial[performer].OR.update(set(requested_resources)) 
    print 'OR after update',self.active_trains[performer].OR 

'OR before update'和'OR after update'行應該給出相同的結果。這沒有發生。 - is - 語句按預期返回False。正在更新全局變量

回答

0

它看起來像你正在修改相同的字典和解釋器行爲正確。

>>> active_trains = {'one':1, 'two':2} 
>>> active_trains_trial = active_trains 
>>> active_trains_trial 
{'two': 2, 'one': 1} 
>>> active_trains_trial['one'] = 1.5 
>>> active_trains 
{'two': 2, 'one': 1.5} 

如果你真的需要一個單獨的字典,你將不得不創建一個副本。

0

這是因爲別名print active_trains_trial is active_trains應打印True雖然我希望你會希望它打印False。這可以通過更改聲明

active_trains_trial = active_trains 

被固定到

active_trains_trial = active_trains.copy() 

進一步說明:

有兩種對象在python:不變可變的值不可更改不可變對象。不可變對象包括數值,字符串和元組等。

代替變量,python有標識符,它們只是指向對象的名稱。您不能更改不可變對象本身的值,但可以更改標識符指向的對象。例如:

var = 3 
var = 4 

不改變int對象3的值,而是重新分配標識符var到int對象4

別名是當不同的名稱被給予相同的對象

var1 = 3 
var2 = 3 

是混疊的不可改變對象3的一個例子。 var1var2都是相同的對象,這可以通過測試以確定id是否相同來證明。這可以通過python中的兩種方式完成:print var1 is var2print id(var1) == id(var2)。這兩個陳述應打印True

但是,這個特殊的例子只適用於不可變的對象。這將與可變和不可變對象工作的一個例子是:

var1 = <object> 
var2 = var1 

別名總是帶着imutable對象安全的,因爲對象本身的價值永遠不會被意外更改。例如:

var1 = 3 
var2 = var1 
var2 = 4 
print var1 
print var2 
print var1 is var2 

時會產生輸出

3 
4 
False 

通知的價值var1如何做到變化。

可變對象另一方面,可以被改變。可變對象包括列表和字典等。因爲雖然L1L2具有相同的,他們相同對象

L1 = [1, 2] 
L2 = [1, 2] 
L3 = L1 
print L1 == L2 
print L1 is L2 
print L1 is L3 

時會產生輸出

True 
False 
True 

。雖然L3被分配到的對象L1,因此他們是同一個對象。

別名可變對象可以是非常危險。原因是如果您使用其中一個標識符更改對象的值,則其他標識符的值的所有也將更改。

L1 = [1, 2, 3] 
L2 = L1 
L2 = [1, 2] 
print L1 
print L2 
print L1 is L2 

時會產生輸出

[1, 2] 
[1, 2] 
True 

通知L1值是如何做到變化。這是因爲L1L2只不過是別名對於相同可變對象

這可以通過創建稱爲副本的對象來避免。隨着名單這是可以做到的:L1 = <list>[:],並且使用詞典是可以做到的是:d1 = <dict>.copy()

L1 = [1, 2, 3] 
L2 = L1[:] 
L2 = [1, 2] 
print L1 
print L2 
print L1 is L2 

產生輸出

[1, 2, 3] 
[1, 2] 
False 

注意如何L1值沒有變化,和L1和L2不是同一個對象。

+0

我在代碼中做了以下更改。 1 - >我創建了一個類,這個函數和這個字典「active_trains」駐留在這個類中。 –

0

我設法找到問題所在。

當創建字典的副本時,會創建映射的副本而不創建正在引用的對象的副本。爲了說明,當我檢查active_trains_local是否爲active_trains時,結果是false,因爲它是active_trains的淺表副本。但是,active_trains_local [執行者] active_trains [執行者]。我終於寫了一個duplicate_registery函數,它創建了一個字典,在active_trains上迭代,並填充新的字典。

def duplicate_registery(self): 
    duplicate_active_trains = {} 
    for name,dataset in self.active_trains.iteritems(): 
     duplicate_active_trains[name] = train_data(copy(dataset.MR),copy(dataset.OR)) 

    return duplicate_active_trains 

這種情況下的值被命名爲tuples(來自collections模塊)。所以,它提出的「數據集」的一個淺拷貝,但即使在這種淺拷貝dataset.MR和dataset.OR相同的對象引用了原始數據集被稱爲

for name,dataset in self.active_trains.iteritems(): 
     duplicate_active_trains[name] = copy(dataset) 

沒有工作。

獲得的經驗:淺拷貝字典,給出映射的淺拷貝。最終的重複映射仍然引用相同的對象。特別感謝@Thomson