Python 具有unicode路径的subprocess.Popen

Python 具有unicode路径的subprocess.Popen,python,windows,unicode,command-line,subprocess,Python,Windows,Unicode,Command Line,Subprocess,我想打开一个unicode文件名。 以下代码: cmd = u'cmd /c "C:\\Pok\xe9mon.mp3"' cmd = cmd.encode('utf-8') subprocess.Popen(cmd) 返回 >>> 'C:\Pokיmon.mp3' is not recognized as an internal or external command, operable program or batch file. 即使文件确实存在。为什么会出现这种情况?

我想打开一个unicode文件名。 以下代码:

cmd = u'cmd /c "C:\\Pok\xe9mon.mp3"'
cmd = cmd.encode('utf-8')
subprocess.Popen(cmd)
返回

>>> 'C:\Pokיmon.mp3' is not recognized as an internal or external command, operable program or batch file.

即使文件确实存在。为什么会出现这种情况?

我认为windows使用16位字符,不确定是UCS2还是UTF16之类的字符。所以我猜它可能与UTF8有问题。

您的问题可以通过Django模块的smart\u str功能解决

使用此代码:

from django.utils.encoding import smart_str, smart_unicode
cmd = u'cmd /c "C:\\Pok\xe9mon.mp3"'
smart_cmd = smart_str(cmd)
subprocess.Popen(smart_cmd)
您可以找到有关如何在Windows上安装Django的信息。 您可以先安装,然后通过启动来安装Django 具有管理员权限的命令shell,并运行此命令:

pip install Django
这将在Python安装的站点包目录中安装Django

>>> subprocess.call(['start', u'avión.mp3'.encode('latin1')], shell=True)
0
如果使用
shell
参数,则无需调用
cmd
启动相关程序的正确方法是使用cmd的
start
内置AFAIK


我的2c,您好。

看起来您正在使用Windows和Python 2.X。使用:

非直观地说,让命令shell做同样的事情是:

>>> import subprocess
>>> import locale
>>> subprocess.Popen(u'Pokémon.mp3'.encode(locale.getpreferredencoding()),shell=True)
在我的系统上,命令shell(cmd.exe)的编码是
cp437
,而Windows程序的编码是
cp1252
Popen
想要的shell命令编码为
cp1252
。这似乎是一个bug,而且在Python 3.X中似乎已修复:

>>> import subprocess
>>> subprocess.Popen('Pokémon.mp3',shell=True)

我认为'cmd'代表其他东西?我删除了双引号,尽管它们与问题无关。您是否包含python path to your path环境变量?假设您的Python安装在C:\Python25中,那么新的path变量应该是:%path%;C:\python25是的,但是
路径
与任何事情都有什么关系?相关:设置为“utf-16”返回
TypeError:必须是没有空字节的字符串或没有,而不是str,所以我想这是错误的。我不会安装一个全新的框架来正确编码unicode。修复应该是一两行长,而不是1000+复杂的代码。好的,对不起,我已经更新了我的答案。也许现在它更有用了。首先,
latin-1
编码不是unicode。它不适用于所有unicode案例。第二,它仍然不起作用。你自己试试看。好的,我在Linux上工作,并用
os.popen
测试了它。。可能windows不起作用..:(我删除了答案的更新部分。有人用Django smart_str制作了一个独立的模块:谢谢你的旁注,但这仍然不能解决unicode问题。这在你的系统上有效,因为你的语言环境MBCS有字符。这段代码在以希伯来语或日语作为语言环境语言的计算机上不起作用。谢谢!我不知道关于
os.startfile
。在Python 2上的Windows上,
Popen(u'Pokémon.mp3'.encode(encode))
Popen(u'Pokémon.mp3'.encode('mbcs')上工作
有效,即在您的情况下,它应该使用
cp1252
成功,而使用
cp437
失败。是否
shell=True
更改了它?sys.getfilesystemencoding()
locale.getpreferredencoding()
的值是什么使用
mbcs可能无法表示。Python3直接使用Unicode API。在Python2上的windows上,如果您想使用Unicode命令行(如Python3),可以使用
ctypes
来修补
子进程。Popen(…)
操作系统启动文件
工作,但
u'pokemon.mp3'.encode](locale.getpreferredencoding())
当然会在ANSI代码页不映射“é”的任何语言环境中失败.In 2.x
subprocess.Popen
调用
CreateProcessA
,它将命令行解码为ANSI,因此它仅限于可以编码为ANSI的命令。如果您需要无法编码为ANSI的命令行,则必须通过ctypes、cffi或扩展模块(如call
CreateProcessW
或CRT函数,如
\u wsystem
.CMD是一个Unicode应用程序。它仅在处理文件和管道时使用代码页对字节进行解码,例如读取批处理脚本的一行或从命令读取标准输出的
for/f
循环。在这种情况下,如果未连接到控制台,则其默认代码页为ANSI。否则,它使用t控制台的输入或输出代码页(CMD不是控制台),除非通过chcp.com更改,否则默认为OEM。在任何情况下,CMD用于文件的编码都是无关的。当CMD看到其命令行时,Windows已将其解码为Unicode。
>>> import subprocess
>>> subprocess.Popen('Pokémon.mp3',shell=True)