2014-04-11 53 views
-1

在下面的代码中运行2.7.6,我使用argparse将命令行参数获取到kwargs字典中。然后我制作一个项目的副本并进行更改。根据字典项目是否开始空,我会得到不同的结果。python“reference to”vs“copy of”字典项目

该例程需要一个位置命令行参数,如COM6,9600,8,none,1,它将进入COM键,但我想为除com端口之外的所有其他参数提供默认参数。

#split up COM params entered as comma delimited 
cp = kwargs['COM'] 
if len(cp)==1: 
    cp = cp[0].split(',') 

# provide defaults 
if len(cp)<5: 
    if len(cp)<4: 
      if len(cp)<3: 
       if len(cp)< 2: 
        if len(cp)==0: 
         cp.append('')  # no default port 
        cp.append(19200)   #baud 
       cp.append(8)     #databits 
      cp.append('none')     #parity 
    cp.append(1)       #stopbits     

print cp 
print kwargs['COM'] 

如果我运行"python myprog.py",没有PARAMS然后打印语句将

['', 19200, 8, 'none', 1] 
['', 19200, 8, 'none', 1] 

这是伟大的。不过,我很惊讶,运行"python myprog.py COM6"产生

['COM6', 19200, 8, 'none', 1] 
['COM6'] 

这意味着,在第一种情况下它是由引用复制,第二次按值复制。解决方法很简单,只需将cp复制回kwargs,但我对结果感到困惑。

任何人都可以解释一下吗?

+5

Oh boy,dat indents – vaultah

+1

如何使用默认列表并根据您已有多少值对其进行分片,并附加分片列表? 'cp + = ['',19200,8,'none',1] [len(cp):]'。这是11行嵌套'if's被一行代替。 –

+1

我更正了你的示例;你*必须*打印'cp'然后'kwargs ['COM']'。这个细节会让答案更快。 :-) –

回答

1

您的代码重新绑定cp当只有一个元素:

cp = kwargs['COM'] 
if len(cp)==1: 
    cp = cp[0].split(',') 

kwargs['COM']cp现在是两个不同的,单独的列表。

如果你想他们是相同列表,使用一个切片赋值,也许是:

cp = kwargs['COM'] 
if len(cp)==1: 
    cp[:] = cp[0].split(',') 

你的深度嵌套if结构并不需要使用嵌套,并且可以被替换为:

cp += ['', 19200, 8, 'none', 1][len(cp):] 

eg根据已存在于cp中的元素数量,将默认值列表分割为大小。

+0

好的。我显然需要多阅读一些关于绑定和切片的知识。这工作和优雅。干杯。 – marcp

1
cp = kwargs['COM'] 

一旦该行执行,cpkwargs['COM']指代相同的对象。如果你使用其中一个追加它,那么这个变化将在另一个变化中显而易见。

 cp = cp[0].split(',') 

一旦发生转让,cp重新绑定,现在指的是一个全新的列表。它不再与kwargs['COM']有任何关系。追加到cp不会更改kwargs

通常,在赋值之后,名称不再有任何关于它以前绑定的内存的内存。

+0

谢谢@凯文,你的回答同样正确。我刚刚看到了Martijn的第一个。 – marcp