2013-05-17 147 views
1

我创建了一个用户自定义指令'getSetpoints',它通过串口读取一组数据,并自动将其转换为4位数字片段,并将其转储到名为GROUP#的列表中(#取决于用户的哪组数据希望)。列表被覆盖?

所有这些工作都很好,我可以在Python shell中打印这些数据,只需输入GROUP0,GROUP1,GROUP2等。运行getSetpoints()函数后,我知道它正在正确存储。但是,现在我想自动将我的GROUP0列表中的每个成员加载到其正确命名的变量(即,Lang_Style是GROUP0 [0],CTinv_Sign是GROUP0 [1]等)。我创建了decodeSP()来做到这一点,我在getSetpoints()结束时调用它。

唯一的问题是,在运行getSetpoints()之后,在python shell中键入Lang_Style(或任何其他的命名变量)时,它只返回0.请参阅下面的代码。我也包含了我的Python shell的输出。

我只是不明白GROUP0在用户定义的指令执行后如何保持它的数据,但其他变量每次都被置回零。据我所知,它是相同的。

# Define Variables (This is shortened to only show one GROUP...) 
GROUP0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

Lang_Style = 0 
CTinv_Sign = 0 
Freq = 0 
PT_Ratio = 0 
CT_Ratio = 0 
DST = 0 
System_Volts = 0 
Gen_Phase = 0 
Op_Mode = 0 
Seq_Pref = 0 
Re_Commit = 0 
Bit_Address = 0 

CRLF = bytearray ([0x0D, 0x0A]) 
RESULTS = [GROUP0, GROUP1, GROUP2, GROUP3, GROUP4, GROUP5] 

def getSetpoints(group): 
    if 0 <= group <= 5: 
     # Send out the command for Display Setpoint, then group number, then CRLF. 
     s = serial.Serial('COM1', '9600') # serial port, baud rate 
     s.write("DP") 
     s.write(group) 
     s.write(CRLF) 
     temp = s.read(len(RESULTS[group])*6) # Each setpoint is 6 characters (space + x + 4 digits). 
     n = 0 
     for n in range(len(RESULTS[group])): 
      # RESULTS[group][n] = int(temp[2+n*6:6+n*6],16) # Use this one if you want Integers 
      RESULTS[group][n] = temp[2+n*6:6+n*6] # Cut out the space and the x, leaving only the 4 digits. 
     print RESULTS[group] # Debug Print 
     s.close() 
     decodeSP() 
     return 
    else: 
     print 'Invalid Group Number' 
     return 

def decodeSP(): 
    Lang_Style = GROUP0[0] 
    CTinv_Sign = GROUP0[1] 
    Freq = GROUP0[2] 
    PT_Ratio = GROUP0[3] 
    CT_Ratio = GROUP0[4] 
    DST = GROUP0[5] 
    System_Volts = GROUP0[6] 
    Gen_Phase = GROUP0[7] 
    Op_Mode = GROUP0[8] 
    Seq_Pref = GROUP0[9] 
    Re_Commit = GROUP0[10] 
    Bit_Address = GROUP0[11] 
return 

化Python Shell输出继电器:

================================ RESTART ================================ 
getSetpoints(0) 
['0004', '0000', '003C', '0000', '00C8', '0001', '0078', '0101', '0000', '0003', '0001', '0001'] 
GROUP0 
['0004', '0000', '003C', '0000', '00C8', '0001', '0078', '0101', '0000', '0003', '0001', '0001'] 
Lang_Style 
0 

回答

1

这是由于改变之间的差对象的值并调用其上的一个方法:

当你在做

RESULTS[group][n] = temp[2+n*6:6+n*6] 

你实际上在结果上调用一个方法(__setitem__)。上述指令扩展为:

RESULTS.__getitem__(group).__setitem__(n, temp.__getslice__(2+n*6, 6+n*6)) 

你没有明确改变RESULTS,你只需调用它的方法,它是给要修改的对象本身。

相反,当你做

Lang_Style = GROUP0[0] 

设置Lang_Style为'GROUP0 [0]。

虽然这并没有完全回答这个问题。你的问题是:为什么不粘?那么,Python可以从高位命名空间(例如decodeSP函数中的全局命名空间)获取值,但它不会覆盖它们。

您可以通过在decodeSP开头指定哪些对象应被视为全局来更改该对象。见http://docs.python.org/release/2.7/reference/simple_stmts.html#the-global-statement

例如

def decodeSP(): 
    global Lang_Style, CTinv_Sign, ... 
+0

Yay!感谢您解释两者之间的差异。 :) – Darksabre

1

你使用它的方式,在decodeSP所有的变量声明为本地。您想写入全局,所以您需要在函数范围内对全局进行引用。使用global关键字来实现这一目标:

def decodeSP(): 
    global Lang_Style 
    global CTinv_Sign 
    global Freq 
    # ... 
    Lang_Style = GROUP0[0] 
    CTinv_Sign = GROUP0[1] 
    Freq = GROUP0[2] 
    # ... 
1

你的功能decodeSP创造了很多具有相同的名称外变量局部变量。既然你不返回任何东西,所有这些变化都会丢失。您将不得不声明所有这些变量global以影响外部范围。

考虑所得重复的量,另一个选项是使用namedtuplecollections模块

from collections import namedtuple 
data = namedtuple('data', 'Lang_Style, CTinv_Sign, Freq, PT_Ratio, CT_Ratio, DST, System_Volts, Gen_Phase, Op_Mode, Seq_Pref, Re_Commit, Bit_Address') 

parsed_data = data(*GROUP0) # need to fill in the array as params 

然后可以访问数据作为

print parsed_data.Lang_Style 
+0

真的,但我不知道怎样 'code'RESULTS [组] [N] =温度[2 + N * 6:6 + N * 6]#切出的空间,而x ,只留下4位 与本地声明它们不同,就像我在decodeSP()中做的那样,但GLOBAL0的行为好像它已经是全局的。 – Darksabre

+0

编辑:德朱尤欧为我回答了上面这个问题。如果你不能说......本周我刚刚开始Python ...... – Darksabre

+0

该行从'RESULT'读取,显然它得到了组的第一个元素。然后你修改这个返回值,通过在循环中设置一个数组项之后的另一个 –