我有以下代码,但我想将其转换为模块。
显然,如果我将此代码作为模块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)
答案 0 :(得分:3)
显然,如果我将此代码作为模块
ser_r
导入,ser
将永远不会被初始化,Agent
类将无法正常工作。
不,这根本不明显,实际上是错误的。导入模块会运行所有顶级代码。这里没有问题,ser_r
和ser
与其他所有内容一起创建。
这里的课程并不特别; class Serial: ...
只是另一个顶级声明,就像ser_r
和ser
声明一样。
请注意,该模块为该模块中的所有代码构成全局命名空间。在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__()
对象。