Python处理Windows路径空格及中文编码问题实战
本文详解Python在Windows环境下处理含空格路径的常见陷阱。通过对比os.popen与subprocess模块,解析管道命令失效原因,并给出切换目录执行命令的替代方案。同时提供解决中文路径Unicode编码错误的实用代码片段,帮助开发者避开常见坑点。
近期在进行Windows中间件数据采集时,遇到了文件路径中包含空格导致的异常问题。
以Apache安装目录为例,其路径通常为D:\Program Files\Apache Software Foundation\Apache2.2。
采集过程需要读取配置文件,路径指向D:\Program Files\Apache Software Foundation\Apache2.2\conf\httpd.conf。
此外还需执行类似D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe -v的系统命令。
读取配置文件本身并无障碍,因为Python代码可以正常打开文件并逐行遍历,通过正则匹配或字符串比较提取信息,例如获取端口号。
port_list=[]
with open(httpd_conf, "r") as f:
file_list = f.readlines()
regex = ur"^Listen\s*(\S*?:)*(\d+)\s*$"
pattern_listener = re.compile(regex)
for item in file_list:
listener_list = pattern_listener.findall(item)
if listener_list:
for port_info in listener_list:
if port_info:
port = port_info[1]
if port and port.strip():
port_list.append(port.strip())
下面重点讨论通过命令获取信息的场景,如D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe -v。
httpd.exe -v用于获取Apache版本信息。如果在cmd命令行中直接输入,会看到如下显示。
D:\>D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe -v
系统报错:'D:\Program' 不是内部或外部命令,也不是可运行的程序或批处理文件。
这是由于路径中存在空格造成的,经搜索发现较好的解决办法是将命令整体用双引号包裹,以下两种写法均可生效。
D:\>"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -v Server version: Apache/2.2.22 (Win32) Server built: Jan 28 2012 11:16:39 D:\>"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" "-v" Server version: Apache/2.2.22 (Win32) Server built: Jan 28 2012 11:16:39
接下来我们在Python中尝试使用os.popen().read()来处理这种情况。
>>> import os >>> cmd='"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -v' >>> os.popen(cmd).read() --这种写法读出来结果为空,是因为\要经过转义,前边加个r就行,cmd与cmd1区别 '' >>> cmd --\b是正则表达式,所以变成了\x08 '"D:\\Program Files\\Apache Software Foundation\\Apache2.2\x08in\\httpd.exe" -v' >>> cmd1=r'"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -v' >>> cmd1 '"D:\\Program Files\\Apache Software Foundation\\Apache2.2\\bin\\httpd.exe" -v' >>> os.popen(cmd1).read() 'Server version: Apache/2.2.22 (Win32)\nServer built: Jan 28 2012 11:16:39\n' >>>
再看一个更复杂的命令:httpd.exe" -V|find "Server MPM",该命令用于获取Apache的运行模式,在Windows下通常对应WinNT。
按照之前的思路,在cmd命令行中执行该命令是可以正常返回结果的。
D:\>"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -V|find "Server MPM" Server MPM: WinNT
若将其移植到Python中,继续使用os.popen().read(),结果却如截图所示,无法获取任何输出。
由此可见,对于参数较多或包含管道符的命令,直接使用这种方法行不通。
>>> cmd1=r'"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -V|find "Server MPM" ' >>> os.popen(cmd1).read() '' >>> cmd2=r'"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -V|find Server MPM ' >>> os.popen(cmd1).read() '' >>> cmd3=r'"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" "-V|find Server MPM" ' >>> os.popen(cmd1).read() ''
查阅相关资料后,发现可以使用subprocess.Popen()来替代os.popen()方法。
然而执行后发现,输出的结果并非预期内容,说明该方法在此场景下也无法直接实现效果(见下图)。
>>> import subprocess >>> cmd=r'D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe -V|find "Server MPM"' >>> cmd 'D:\\Program Files\\Apache Software Foundation\\Apache2.2\\bin\\httpd.exe -V|find "Server MPM"' >>> ps = subprocess.Popen(cmd) >>> Server version: Apache/2.2.22 (Win32) Server built: Jan 28 2012 11:16:39 Server's Module Magic Number: 20051115:30 Server loaded: APR 1.4.5, APR-Util 1.4.1 Compiled using: APR 1.4.5, APR-Util 1.4.1 Architecture: 32-bit Server MPM: WinNT threaded: yes (fixed thread count) forked: no
面对上述结果,经过多次尝试无果后,最终选择了一种曲线救国的方案:利用Python的os模块,先切换到httpd.exe所在的目录,再执行命令。
>>> homepath="D:\Program Files\Apache Software Foundation\Apache2.2"
>>> BinPath = os.path.join(homepath, 'bin')
>>> os.chdir(BinPath)
>>> apache_model = os.popen('httpd.exe -V |find "Server MPM"').read()
>>> print apache_model
Server MPM: WinNT
补充知识:Python在Windows下处理含中文路径时的编码问题。
在Windows中使用os.path.abspath(__file__)时,若路径包含中文,默认会转换为非Unicode格式。
这会导致其他模块在使用该路径时报错。
错误信息通常为:utf8' codec can't decode byte 0xb7 in position 14: invalid start byte。
该如何处理这种情况?
网上搜索的解决方法大多不够妥当,这里提供一种非通用但非常实用的方案。
具体代码如下。
project_path = os.path.abspath(__file__.decode('gbk'))
使用该方法既简单又便捷。
以上关于Python解决Windows平台路径空格问题的内容就是小编分享给大家的全部,希望能对大家有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













