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
4

3 回答 3

1

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

def decodeSP():
    global Lang_Style
    global CTinv_Sign 
    global Freq
    # ...
    Lang_Style = GROUP0[0]
    CTinv_Sign = GROUP0[1]
    Freq = GROUP0[2]
    # ...
于 2013-05-17T22:02:09.617 回答
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
于 2013-05-17T22:08:43.313 回答
1

这是由于更改对象的值和在其上调用方法之间的区别:

当你这样做时

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

__setitem__您实际上在 RESULTS 上调用了一个方法 ( )。上述指令扩展为:

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, ...
于 2013-05-17T22:17:11.667 回答