2015-09-02 61 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