2017-05-14 219 views
0

我有以下代码,但我想将其转换为模块。 很显然,如果我将此代码作为模块丢失并且ser将永远不会初始化,并且Agent类将不起作用。Python模块全局变量

#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) 

于是我想出了一个主意,以创建具有ser变量,然后在Agent类使用Serial类。

但现在还有另一个问题:如何在Agent内部访问Serial而不创建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) 

回答

3

显然,如果我导入此代码模块ser_rser将永远不会被初始化,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类。它没有状态(只有类的属性),所以你永远不需要创建一个实例,你可以把它作为一个全局的(因为你的第二次尝试已经)。因为你已经可以从Agent().send()访问全球Serial,所以不需要任何人使用你的模块必须知道Serial或创建它的一个实例。

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