Python模块全局变量

时间:2017-05-14 11:07:57

标签: python pyserial

我有以下代码,但我想将其转换为模块。 显然,如果我将此代码作为模块ser_r进行操作,ser将永远不会被初始化,Agent类将无法正常工作。

#module.py

class Agent:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def send(self, data):
        message = data + ' ' + a
        ser.write(message)

ser_r = serial.Serial(
                    port='COM6',
                    baudrate=500000,
                    parity=serial.PARITY_NONE,
                    stopbits=serial.STOPBITS_ONE,
                    bytesize=serial.EIGHTBITS
                    )

ser = io.TextIOWrapper(io.BufferedRWPair(self.ser_raw, self.ser_raw, 1),
                   newline='\r',
                   line_buffering=True)

所以我提出了创建具有Serial变量的类ser的想法,然后在Agent类中使用该变量。

但现在还有另一个问题:如何在不创建Serial实例的情况下访问Agent内的Serial?用户可以创建Serial个实例,但我不知道我应该在Agent内使用的名称。我可以创建init方法,然后在里面创建Serial类。导入后,用户会调用init方法,然后他可以使用它。

#module.py

class Agent:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def send(self, data):
        message = data + ' ' + a
        Serial.ser.write(message)



class Serial:
    ser_r = serial.Serial(
                port='COM6',
                baudrate=500000,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE,
                bytesize=serial.EIGHTBITS
            )

    ser = io.TextIOWrapper(io.BufferedRWPair(self.ser_raw, self.ser_raw, 1),
                               newline='\r',
                               line_buffering=True)

1 个答案:

答案 0 :(得分:3)

  

显然,如果我将此代码作为模块ser_r导入,ser将永远不会被初始化,Agent类将无法正常工作。

不,这根本不明显,实际上是错误的。导入模块会运行所有顶级代码。这里没有问题,ser_rser与其他所有内容一起创建。

这里的课程并不特别; class Serial: ...只是另一个顶级声明,就像ser_rser声明一样。

请注意,该模块为该模块中的所有代码构成全局命名空间。在Agent.send()中,名称ser是全局名称,通过查看已存在ser的附加模块全局变量来解析该名称。

但是代码中确实有错误:

ser = io.TextIOWrapper(io.BufferedRWPair(self.ser_raw, self.ser_raw, 1),
                   newline='\r',
                   line_buffering=True)

没有定义全局名称self,因此self.ser_raw也不存在。也许您打算围绕ser_r创建包装器?

ser = io.TextIOWrapper(io.BufferedRWPair(ser_r, ser_r, 1),
                       newline='\r', line_buffering=True)

这意味着您实际上不必使用Serial课程。它没有状态(只有类属性),所以你永远不需要创建一个实例,你可以把它当作全局(因为你的第二次尝试已经)。由于已经可以访问Serial的{​​{1}}全局,因此使用您的模块的任何人都不需要了解Agent().send()或创建实例它的。

如果您不想使串行连接成为全局连接,则可以始终在Serial中创建连接,或者让该类接受要写入的合适Agent.__init__()对象。