[英]converting the python queue module from python2 to python3
我有一个日志记录脚本,它将串行项队列中多个设备的串行输出记录到标准输出中。 在 python 2.7 中,脚本按预期工作。 但是,将脚本转换为 python3. 我注意到,在将队列模块转换为它的 python3 形式后,我的脚本开始打印除了常规预期输出之外的空行。 有人可以解释这是什么原因以及解决此问题的任何最佳做法吗?
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import serial
import sys
import threading
from datetime import datetime
import glob
import time
import os
import termcolor as tc
import queue
__version__ = 2.0
COLOR = True
# Available colors
# blue, yellow, green, cyan,
# magenta, white, red, grey,
# light_grey, on_red
# Add light grey to the colors dictionary
tc.COLORS['light_grey'] = 38
# Add a highlight color
tc.COLORS['on_red'] = 41
TIMEOUT = 0.05 # seconds
DEVS = []
usb_devices = []
speaker_types = ['Tx', 'Rx-FL', 'Rx-FR', 'Rx-Center', 'Rx-Subwoofer']
stamp = time.strftime("%Y:%m:%d-%H:%M:%S")
def serial_ports():
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
result.reverse()
print("Ports: " + str(result))
pattern = 'USB'
usb_devices = [string for string in result if pattern in string]
return usb_devices
def add_device(position):
name = speaker_types[position]
return name
class SerialTerm(object):
"""A serial terminal that runs in its own thread"""
def __init__(self, name, port, timeout, queue, baudrate=2000000, color=None):
self.name = name
self.port = port
self.timeout = timeout
self.queue = queue
self.baudrate = baudrate
self.color = color
self.receiver_thread = None
self.alive = None
self.serial = serial.serial_for_url(
self.port,
timeout=self.timeout,
baudrate=self.baudrate)
def start(self):
"""Starts the terminal thread"""
self.alive = True
self.receiver_thread = threading.Thread(target=self.reader)
self.receiver_thread.setDaemon(True)
self.receiver_thread.start()
#self.reset()
def stop(self):
"""Stops the terminal thread"""
self.alive = False
self.receiver_thread.join()
def reader(self):
"""Reads data from the associated serial port and puts the data in a
queue"""
while self.alive:
now = datetime.utcnow()
line = self.serial.readline()
if line != "":
output_str = f"{now.time().isoformat()[:12]}(UTC) {self.name}> {line}"
if COLOR and (self.color is not None):
output_str = tc.colored(output_str, self.color)
self.queue.put(output_str)
def join(self):
"""Waits until thread terminates"""
self.receiver_thread.join()
def main():
print("Getting Devices")
dev = serial_ports()
position = 0
name = ''
for d in dev:
name = add_device(position)
DEVS.append({'port':dev[position], 'name':name, 'color':'white'})
position += 1
print('DEVS: ' + str(DEVS))
"""Round robin serial polling"""
sys.stdout.write("v{}\n".format(__version__))
sys.stdout.flush()
que = queue.Queue()
terms = []
for dev in DEVS:
terms.append(
SerialTerm(
name=dev['name'],
port=dev['port'],
color=dev['color'],
timeout=TIMEOUT,
queue=que))
for term in terms:
term.start()
try:
while True:
try:
# The queue.get method needs a timeout or KeyboardInterrupt won't ever raise.
sys.stdout.write(que.get(timeout=60) + "\n")
sys.stdout.flush()
except queue.Empty:
pass
except KeyboardInterrupt:
sys.stderr.write("\nQuitting\n")
for term in terms:
term.stop()
term.join()
sys.exit()
sys.stdout.flush()
except:
raise
if __name__ == '__main__':
main()
这是 python3 给我的错误输出示例。 除了显示的任何正常打印输出之外,它只会无限期地向这些空行发送垃圾邮件。
00:53:00.859(UTC) Tx> b''
00:53:00.909(UTC) Tx> b''
00:53:00.960(UTC) Tx> b''
00:53:01.010(UTC) Tx> b''
00:53:01.061(UTC) Tx> b''
00:53:01.111(UTC) Tx> b''
00:53:00.859(UTC) Tx> b'Expected Printout'
00:53:00.909(UTC) Tx> b''
00:53:00.960(UTC) Tx> b''
00:53:01.010(UTC) Tx> b''
00:53:01.061(UTC) Tx> b''
00:53:01.111(UTC) Tx> b''
错误在这里:
line = self.serial.readline()
if line != "":
output_str = f"{now.time().isoformat()[:12]}(UTC) {self.name}> {line}"
if COLOR and (self.color is not None):
output_str = tc.colored(output_str, self.color)
self.queue.put(output_str)
self.serial.readline()
返回一个bytes
对象。 结果,它不会比较等于str
对象,例如""
,因此不再过滤掉空行。
要修复它,您需要使用bytes.decode
将self.serial.readline()
的返回值转换为str
有关在 python 3 中对字符串所做的更改以及如何正确移植 python 2 代码的更多详细信息, 请参阅本指南。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.