Python pySerial - 使用子类时出现问题
Python pySerial - Problem using subclasses
我正在 Python 中进行一个项目,该项目使用两个或多个串行端口来管理我的 RPi 中的一些设备。当端口在同一文件中打开并且我向 serial.Serial 对象的不同实例发送命令时,一切正常。这是一个例子:
import serial
device1_port = "/dev/ttyUSB0"
device2_port = "/dev/ttyUSB1"
# Command sent to device 1. No problem
d1 = serial.Serial(device1_port, timeout = 0.5)
d1.write(b'GET MUTE\n')
output1 = d1.readline()
print("Device 1 output: " + str(output1))
# Command sent to device 2. No problem
d2 = serial.Serial(device2_port, timeout = 1)
d2.write(b'00vP\r')
output2 = d2.readline()
print("Device 2 output: " + str(output2))
输出:
Device 1 output: b'DATA MUTE OFF\r\n'
Device 2 output: b'00vP0\r'
当我尝试使用 serial.Serial 的子类将一台设备与另一台设备分开时,问题就来了。原因是我想用自己的方法像处理对象一样处理它们(每个设备都需要很多不同的命令、状态查询...)。
class device1(serial.Serial):
def __init__(self, port, timeout):
super().__init__(port, timeout)
serial.Serial(port, timeout)
def command1(self):
self.write(b'SET MUTE OFF\n')
self.write(b'GET MUTE\n')
output = self.readline()
print("Device 1 output: " + str(output))
class device2(serial.Serial):
def __init__(self, port, timeout):
super().__init__(port, timeout)
serial.Serial(port, timeout)
def command2(self):
self.write(b'00vP\r')
output = self.readline()
print("Device 2 output: " + str(output))
device1_port = "/dev/ttyUSB0"
device2_port = "/dev/ttyUSB1"
d1 = device1(device1_port, timeout=0.5)
d2 = device2(device2_port, timeout=1)
d1.command1()
d2.command2()
当我运行这段代码的输出是:
Device 1 output: b'DATA MUTE OFF\r\n'
_
它一直在等待第二个设备。我被迫按 Ctrl + C,我得到了这个:
^CTraceback (most recent call last):
File "./ct3.py", line 35, in <module>
d2.command2()
File "./ct3.py", line 23, in command2
output = self.readline()
File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 483, in read
ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
KeyboardInterrupt
这两个子类之间似乎存在某种冲突,但显然我不知道我做错了什么。
有人可以帮我吗?
你不应该从你的__init__
打电话给serial.Serial(port, timeout)
,
因为 super().__init__(...)
已经在这样做了。参见 these answers。如果您不打算更改基础 class 的功能,您甚至不需要 __init__
。
此外,您的两个版本在位置参数和关键字参数的使用方面存在差异。 serial.Serial()
的前2个位置参数是port, baudrate
,所以需要显式使用关键字参数timeout=
:
def __init__(self, port, timeout):
super().__init__(port, timeout=timeout)
我正在 Python 中进行一个项目,该项目使用两个或多个串行端口来管理我的 RPi 中的一些设备。当端口在同一文件中打开并且我向 serial.Serial 对象的不同实例发送命令时,一切正常。这是一个例子:
import serial
device1_port = "/dev/ttyUSB0"
device2_port = "/dev/ttyUSB1"
# Command sent to device 1. No problem
d1 = serial.Serial(device1_port, timeout = 0.5)
d1.write(b'GET MUTE\n')
output1 = d1.readline()
print("Device 1 output: " + str(output1))
# Command sent to device 2. No problem
d2 = serial.Serial(device2_port, timeout = 1)
d2.write(b'00vP\r')
output2 = d2.readline()
print("Device 2 output: " + str(output2))
输出:
Device 1 output: b'DATA MUTE OFF\r\n'
Device 2 output: b'00vP0\r'
当我尝试使用 serial.Serial 的子类将一台设备与另一台设备分开时,问题就来了。原因是我想用自己的方法像处理对象一样处理它们(每个设备都需要很多不同的命令、状态查询...)。
class device1(serial.Serial):
def __init__(self, port, timeout):
super().__init__(port, timeout)
serial.Serial(port, timeout)
def command1(self):
self.write(b'SET MUTE OFF\n')
self.write(b'GET MUTE\n')
output = self.readline()
print("Device 1 output: " + str(output))
class device2(serial.Serial):
def __init__(self, port, timeout):
super().__init__(port, timeout)
serial.Serial(port, timeout)
def command2(self):
self.write(b'00vP\r')
output = self.readline()
print("Device 2 output: " + str(output))
device1_port = "/dev/ttyUSB0"
device2_port = "/dev/ttyUSB1"
d1 = device1(device1_port, timeout=0.5)
d2 = device2(device2_port, timeout=1)
d1.command1()
d2.command2()
当我运行这段代码的输出是:
Device 1 output: b'DATA MUTE OFF\r\n'
_
它一直在等待第二个设备。我被迫按 Ctrl + C,我得到了这个:
^CTraceback (most recent call last):
File "./ct3.py", line 35, in <module>
d2.command2()
File "./ct3.py", line 23, in command2
output = self.readline()
File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 483, in read
ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
KeyboardInterrupt
这两个子类之间似乎存在某种冲突,但显然我不知道我做错了什么。
有人可以帮我吗?
你不应该从你的__init__
打电话给serial.Serial(port, timeout)
,
因为 super().__init__(...)
已经在这样做了。参见 these answers。如果您不打算更改基础 class 的功能,您甚至不需要 __init__
。
此外,您的两个版本在位置参数和关键字参数的使用方面存在差异。 serial.Serial()
的前2个位置参数是port, baudrate
,所以需要显式使用关键字参数timeout=
:
def __init__(self, port, timeout):
super().__init__(port, timeout=timeout)