如何让Python脚本中的语句像在交互式shell中执行一样?
我有一个仪器,它连接在串口上。我在Windows XP上使用Python 3.2和pySerial模块。现在我遇到一个问题,就是当我执行一个脚本,这个脚本包含了一系列打开串口、配置串口、写入字符串和接收字符串的语句时,出现了一些问题。这些字符串要么是控制仪器的命令,要么是仪器的响应。
当我在Python的交互模式下(也就是在>>>后面)执行这些语句时,结果是我预期的,效果很好且正确。然而,当我在脚本中执行这些语句,无论是在交互模式还是在命令行中,我得到的结果却不如意。脚本中的语句和我在交互模式下使用的是一样的。
为什么会出现这种奇怪的情况?我该如何修改脚本,让它的表现和交互模式一样呢?
def read(comport):
wrt_str=b'movt 3000'+b'\r\n'
ret_str=comport.write(wrt_str)
wrt_str=b'scan'+b'\r\n'
ret_str=comport.write(wrt_str)
rsp_str=comport.readlines() #########1
wrt_str=b'hllo'+b'\r\n'
ret_str=comport.write(wrt_str)
rsp_str=comport.readlines()#########2
问题出在上面带有#######的几行。在交互模式下,第一个地方有大约1秒的延迟,第二个地方有9秒的延迟。这个时候我能得到正确的响应。然而,如果我执行上面的脚本,就没有任何延迟,结果却是错误的(垃圾数据)。我在串口设置中将读取超时设置为0,像这样:
comport.timeout=0
所以串口应该处于阻塞模式,这样它才能等待行结束或文件结束。
更新(2011年8月19日)
我对几天前发的原始帖子有了更新。我想我知道问题出在哪里了,想看看有没有人能提供解决方案:
在每个语句后面加上“print”和“time.sleep(delay)”后,我发现当脚本运行时,它似乎在绕过pyserial的语句,比如“comport.write(..)”或“comport.readlines(...)”,而这些pyserial命令正在执行(看起来像是在等待,串口的速度比较慢)。举个例子,当我在Python的交互式环境中执行所有语句时,如果前一个语句没有返回,我就无法输入并运行新的语句。比如说,如果comport.readlines()没有返回,我就不能输入并运行下一个comport.write(...)的语句。然而,在运行的脚本中,如果comport.readlines()正在忙着读取,下一条语句仍然会执行,如果下一条语句恰好是comport.write(),这就会中断读取。
有没有办法强制Python脚本按顺序执行呢?
3 个回答
试着在每个 comport.write
之后加一个暂停(比如用 time.sleep(1)
),这样可以给设备一些时间来响应每个命令,然后再去查看响应。
正如 HYRY 提到的,把 timeout
设置为 0
会立即返回,所以它并不会像你想的那样工作。此外,当你逐行输入命令时,每输入一行都会有一些延迟。而在脚本中执行这些命令时,它们之间几乎没有间隔。
我建议把每个命令字符串放到自己的函数里,然后一个接一个地调用这些函数,中间加一些暂停。
另外,如果你知道输出数据字符串的长度,可以设置你的 read()
或 readlines()
在读取到指定的字节数后停止,或者如果你的读取字符串长度不固定,也可以设置一个任意的数字来停止。
我看了pyserial的文档:
timeout = None: wait forever
timeout = 0: non-blocking mode (return immediately on read)
timeout = x: set timeout to x seconds (float allowed)
如果你把comport.timeout设置为0,那么readlines()会立刻返回结果。试着把comport.timeout设置为10吧。