从含有serial_for_url的脚本中提取可执行文件
我写了一个Python脚本,用来和一个数字泵进行串行通信。现在我想把它做成一个可执行文件。不过,虽然在用Python运行时一切都很好,而用py2exe生成的.exe文件也没问题,但当我运行这个可执行文件时,出现了以下错误:
File: pump_model.pyc in line 96 in connect_new
File: serial\__init__.pyc in line 71 in serial_for_url
ValueError: invalid URL protocol 'loop' not known
我代码中相关的部分是这样的: # 新的串行连接 def connect_new(self, port_name): """配置新的串行连接的函数。"""
try:
self.ser = serial.Serial(port = port_name,\
baudrate = 9600,\
parity = 'N',\
stopbits = 1,\
bytesize = 8,\
timeout = self.timeout_time)
except serial.SerialException:
self.ser = serial.serial_for_url('loop://',\
timeout = self.timeout_time) # This line BLOWS!
except:
print sys.exc_info()[0]
finally:
self.initialize_pump()
我需要说明的是,这个应用是在OSX上写的,并且在Windows上用Canopy Python Distribution进行了测试。
2 个回答
我遇到的问题和“socket://”一样,而不是“loop://”。
不过我没能让大家推荐的解决办法奏效,但下面的方法似乎成功了:
1) 明确导入有问题的 urlhandler.* 模块。
import serial
# explicit import for py2exe - to fix "socket://" url issue
import serial.urlhandler.protocol_socket
# explicit import for py2exe - to fix "loop://" url issue (OP's particular prob)
import serial.urlhandler.protocol_loop
# use serial_for_url in normal manner
self._serial = serial.serial_for_url('socket://192.168.1.99:12000')
2) 为 py2exe 生成一个设置脚本(可以参考 https://pypi.python.org/pypi/py2exe/)—— 我是在一个虚拟环境中安装了 py2exe:
path\to\env\Scripts\python.exe -m py2exe myscript.py -W mysetup.py
3) 编辑 mysetup.py 文件,加入选项。
zipfile="library.zip" # default generated value is None
(也可以查看 http://www.py2exe.org/index.cgi/ListOfOptions)
4) 构建它:
path\to\env\Scripts\python.exe mysetup.py py2exe
5) 运行它。
dist\myscript.exe
找到了!
看起来由于某种原因,'loop://'这个参数在生成.exe文件后无法被识别。
我通过研究pyserial/init.py这个脚本发现,当你发出命令serial.serial_for_url(‘loop://')时,实际上是在调用: sys.modules['serial.urlhandler.protocol_loop’].Serial(“loop://“)
所以你需要先导入serial.urlhandler.protocol_loop,然后用这个命令替代那个出问题的命令。
这样你现在可以输入:
__import__('serial.urlhandler.protocol_loop')
sys.modules[‘serial.urlhandler.protocol_loop’].Serial("loop://")
经过这个小小的变通后,一切正常了。