Python新手 - 傻问题?在Python解释器中有效,但在CLI中无效

3 投票
3 回答
1143 浏览
提问于 2025-04-16 06:14

我希望这只是一个简单的初学者错误,只需要在某个地方加一行代码就能解决。

我正在使用pySerial从USB端口读取串口数据,并将其打印到标准输出。我在使用Mac OSX 10.6。我打开终端,输入“python”,然后输入以下内容:

>>> import serial;
>>> ser = serial.Serial('/dev/tty.usbserial-XXX', 9600, timeout=1);
>>> while True:
>>>      if ser.inWaiting() > 0:
>>>            ser.readline();
>>> [done, I hit enter...]

这运行得很好。它开始漂亮地输出我的串口数据,正如我所期待的那样。我心想,太好了,让我把它放到一个脚本里,并加上命令行参数,这样我就可以随时调用它:

import sys;
import serial;

serialPort = sys.argv[1]
baudRate = sys.argv[2]

ser = serial.Serial(serialPort, baudRate, timeout=1)

while True:
    if ser.inWaiting() > 0:
        ser.readline()

在命令行中,我输入“python myScript.py [我的串口] 9600”,然后坐等美妙的串口数据流出来——但什么都没有。它就这样卡住了,直到我强制结束这个进程。

我想,可能是某种原因导致它不工作——所以我在代码里加了一些调试打印。我把我的循环更新成这样:

 while True:
    print("looping...")
    print(ser.inWaiting());
    if ser.inWaiting() > 0:
        ser.readline()

我再次运行它,得到了重复的输出流“Looping...”和“0”。我想,可能是我的命令行参数有问题——所以我把端口和波特率硬编码到脚本里,结果还是一样。

那么,这是什么原因呢?我使用while True:是否以某种方式阻止了脚本接收串口数据?有没有更好的方法来实现这个?

我完全是个Python新手。我写这个脚本是为了创建一个更快的方式来在Adobe AIR和Arduino板之间进行通信。我希望这里能有一个简单的解决办法,让它工作——有吗?

3 个回答

0

我使用 while True: 这样写,会不会阻止脚本接收串口数据呢?

不会的。这种写法是非常常见的,完全不会影响输入输出。while True 和 C 语言里的 while 1 是一样的。

有没有更好的方法呢?

我和其他人一样,对你的参数有些担心。这样做会更可靠一些:

from sys import argv
from serial import Serial

try:
    baudRate = int(argv[-1])
    serialPort = argv[1:-1]
except ValueError:
    #some nice default
    baudRate = 9600
    serialPort = argv[1:]

#support paths with spaces. Windows maybe?
serialPort = ' '.join(serialPort)
if not serialPort:
    exit("Please specify a serial port")

print( "reading from %r@%i ..." % (serialPort, baudRate) )
ser = Serial(serialPort, baudRate, timeout=1)    
while True:
    if ser.inWaiting() > 0:
        print( ser.readline() )

如果这样还是不行,请检查一下你是否在使用同一个解释器,可以在脚本和命令行中运行这些代码来确认。

import sys
print("Executable: " + sys.executable)
print("Version: " + sys.version)
1

在你的第一个例子中,波特率是一个整数,但在第二个例子里,你没有把 sys.argv[2] 从字符串转换过来。试试这个 ser = serial.Serial(serialPort, int(baudRate), timeout=1)

1

它有没有打印出什么东西?我猜它会打印:

looping...
<ser.inWaiting() val>

然后就什么都不打印了。加一个打印语句,让它看起来像这样:

print ser.readline()

然后看看这样是否有效。我猜在你直接输入命令的时候,解释器会打印出返回的字符串,但在脚本中,readline() 返回的字符串可能被忽略掉了。

撰写回答