为什么会出现以下情况:
>>> u'\u0308'.encode('mbcs') #UMLAUT
'\xa8'
>>> u'\u041A'.encode('mbcs') #CYRILLIC CAPITAL LETTER KA
'?'
>>>
我有一个Python应用程序接受来自操作系统的文件名。它适用于一些国际用户,但不适用于其他用户。
例如,此unicode文件名: u'\u041a\u0433\u044b\u044b\u0448\u0444\u0442'
不会使用Windows“mbcs”编码(文件系统使用的编码,由sys.getFileSystemCoding()返回)。我明白了,表示编码器在这些字符上失败。但这毫无意义,因为文件名是从用户开始的。
更新:这是我背后的原因背景。。。 我的系统中有一个用西里尔文命名的文件。我想用那个文件作为参数调用subprocess.Popen()。Popen不能处理unicode。通常,我可以使用sys.getFileSystemCoding()提供的编解码器对参数进行编码。在这种情况下是行不通的
在Py3K中,至少来自Python 3.2-
subprocess.Popen
和sys.argv
的字符串与Windows上的(默认unicode)字符串一致。CreateProcessW
和GetCommandLineW
使用明显。在Python中-到v2.7.2版本至少-
subprocess.Popen
有Unicode参数的错误。它坚持CreateProcessA
(而os.*
与Unicode一致)。而且shlex.split
会产生额外的废话。Pywin32的
win32process.CreateProcess
也不会自动切换到W版本,也没有win32process.CreateProcessW
。与GetCommandLine
相同。 因此需要使用ctypes.windll.kernel32.CreateProcessW...
。 关于这个问题,可能应该修复子流程模块。在Unicode操作系统上,使用私有应用程序的UTF8仍然很笨拙。对于像Linux这样的8位“Latin1”字符串操作系统,这样的技巧可能是合法的。
更新vaab为Python 2.7创建了
Popen
的修补版本,该版本修复了该问题。见https://gist.github.com/vaab/2ad7051fc193167f15f85ef573e54eb9
有解释的博客文章:http://vaab.blog.kal.fr/2017/03/16/fixing-windows-python-2-7-unicode-issue-with-subprocesss-popen/
免责声明:我是下面提到的修复程序的作者。
要在带有Python2.7的windows上支持unicode命令行,可以使用 this patch到
subprocess.Popen(..)
情况
Python 2在windows上对unicode命令行的支持非常差。
被严重窃听:
从调用方向系统发出unicode命令行(通过
subprocess.Popen(..)
),从被叫方读取当前的命令行unicode参数(通过
sys.argv
),它在Python 2上被确认并won't be fixed。这些在Python 3中是固定的。
技术原因
在Python 2中,
subprocess.Popen(..)
和sys.argv
的windows实现使用非unicode就绪的windows系统调用CreateProcess(..)
(请参见Pythoncode,和MSDNdoc of CreateProcess),而不使用GetCommandLineW(..)
来获取sys.argv
。在Python 3中,GetCommandLineW(..)从
subprocess.Popen(..)
的windows实现使用正确的windows系统调用CreateProcessW(..)
从3.0
开始(请参见3.0
中的^{3.3
开始(请参见3.3
中的^{如何修复
给定的patch将利用
ctypes
模块调用C窗口 直接系统CreateProcessW(..)
。它通过重写私有方法Popen._execute_child(..)
和私有函数_subprocess.CreateProcess(..)
从windows系统库中设置和使用CreateProcessW(..)
,提出了一个新的固定Popen
对象,以尽可能模拟在Python中的工作方式3.6
。如何使用它
如何使用给定的修补程序将通过blog post explanation演示。它还显示了如何读取当前进程
sys.argv
与another fix一起。Docs for sys.getfilesystemencoding()假设对于Windows NT和更高版本,文件名本机是Unicode。如果您有一个有效的unicode文件名,为什么还要用mbcs编码呢?
Docs for codecs module假设mbcs使用“ANSI代码页”(根据用户的语言环境而不同)进行编码,因此如果语言环境不使用西里尔字符,请splat。
编辑:所以您的进程正在调用subprocess.Popen()。如果您调用的进程在您的控制下,这两个进程可以同意使用UTF-8作为Unicode传输格式。否则,您可能需要询问pywin32邮件列表。在任何情况下,编辑您的问题以说明您对调用的流程的控制程度。
相关问题 更多 >
编程相关推荐