Cra*_*een 29 python windows unicode command-line python-2.x
我希望我的Python脚本能够在Windows中读取Unicode命令行参数.但似乎sys.argv是以某种本地编码而不是Unicode编码的字符串.如何以完整的Unicode读取命令行?
示例代码: argv.py
import sys
first_arg = sys.argv[1]
print first_arg
print type(first_arg)
print first_arg.encode("hex")
print open(first_arg)
Run Code Online (Sandbox Code Playgroud)
在我为日语代码页设置的PC上,我得到:
C:\temp>argv.py "PC???????08.09.24.doc"
PC???????08.09.24.doc
<type 'str'>
50438145835c83748367905c90bf8f9130382e30392e32342e646f63
<open file 'PC???????08.09.24.doc', mode 'r' at 0x00917D90>
Run Code Online (Sandbox Code Playgroud)
这是我认为的Shift-JIS编码,并且它"适用于"该文件名.但它打破了文件名,其中的字符不在Shift-JIS字符集中 - 最终的"打开"调用失败:
C:\temp>argv.py Jörgen.txt
Jorgen.txt
<type 'str'>
4a6f7267656e2e747874
Traceback (most recent call last):
File "C:\temp\argv.py", line 7,
in <module>
print open(first_arg)
IOError: [Errno 2] No such file or directory: 'Jorgen.txt'
Run Code Online (Sandbox Code Playgroud)
注意 - 我在谈论Python 2.x,而不是Python 3.0.我发现Python 3.0提供sys.argv了正确的Unicode.但是转换到Python 3.0还有点早(由于缺乏第三方库支持).
更新:
一些答案说我应该根据sys.argv编码的内容进行解码.问题在于它不是完整的Unicode,因此某些字符不可表示.
这是让我感到悲伤的用例:我已经在Windows资源管理器中将文件拖放到.py文件中.我有各种字符的文件名,包括一些不在系统默认代码页中的字符.在所有情况下,当在当前代码页编码中无法表示字符时,我的Python脚本无法通过sys.argv获取正确的Unicode文件名.
肯定有一些Windows API用完整的Unicode读取命令行(而Python 3.0就是这样).我假设Python 2.x解释器没有使用它.
Cra*_*een 29
这是我正在寻找的解决方案,调用Windows GetCommandLineArgvW函数:
在Windows下获取带有Unicode字符的sys.argv(来自ActiveState)
但我做了一些改动,以简化其使用并更好地处理某些用途.这是我使用的:
win32_unicode_argv.py
"""
win32_unicode_argv.py
Importing this will replace sys.argv with a full Unicode form.
Windows only.
From this site, with adaptations:
http://code.activestate.com/recipes/572200/
Usage: simply import this module into a script. sys.argv is changed to
be a list of Unicode strings.
"""
import sys
def win32_unicode_argv():
"""Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode
strings.
Versions 2.x of Python don't support Unicode in sys.argv on
Windows, with the underlying Windows API instead replacing multi-byte
characters with '?'.
"""
from ctypes import POINTER, byref, cdll, c_int, windll
from ctypes.wintypes import LPCWSTR, LPWSTR
GetCommandLineW = cdll.kernel32.GetCommandLineW
GetCommandLineW.argtypes = []
GetCommandLineW.restype = LPCWSTR
CommandLineToArgvW = windll.shell32.CommandLineToArgvW
CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)]
CommandLineToArgvW.restype = POINTER(LPWSTR)
cmd = GetCommandLineW()
argc = c_int(0)
argv = CommandLineToArgvW(cmd, byref(argc))
if argc.value > 0:
# Remove Python executable and commands if present
start = argc.value - len(sys.argv)
return [argv[i] for i in
xrange(start, argc.value)]
sys.argv = win32_unicode_argv()
Run Code Online (Sandbox Code Playgroud)
现在,我使用它的方式就是:
import sys
import win32_unicode_argv
Run Code Online (Sandbox Code Playgroud)
从那时起,sys.argv是一个Unicode字符串列表.Python optparse模块似乎很乐意解析它,这很棒.
mon*_*kut 12
处理编码非常令人困惑.
我相信,如果您通过命令行输入数据,它将编码数据,无论您的系统编码是什么,并且不是unicode.(即使复制/粘贴也应该这样做)
因此,使用系统编码解码为unicode应该是正确的:
import sys
first_arg = sys.argv[1]
print first_arg
print type(first_arg)
first_arg_unicode = first_arg.decode(sys.getfilesystemencoding())
print first_arg_unicode
print type(first_arg_unicode)
f = codecs.open(first_arg_unicode, 'r', 'utf-8')
unicode_text = f.read()
print type(unicode_text)
print unicode_text.encode(sys.getfilesystemencoding())
Run Code Online (Sandbox Code Playgroud)
运行以下将输出:提示> python myargv.py"PC·ソフト申请书08.09.24.txt"
PC???????08.09.24.txt
<type 'str'>
<type 'unicode'>
PC???????08.09.24.txt
<type 'unicode'>
????
Run Code Online (Sandbox Code Playgroud)
"PC·ソフト申请书08.09.24.txt"中包含文字"日本语".(我使用Windows记事本将文件编码为utf8,我有点难以理解为什么打印时会出现'?'.与记事本如何保存utf8有什么关系?)
字符串'decode'方法或内置的unicode()可用于将编码转换为unicode.
unicode_str = utf8_str.decode('utf8')
unicode_str = unicode(utf8_str, 'utf8')
Run Code Online (Sandbox Code Playgroud)
此外,如果您处理编码文件,您可能希望使用codecs.open()函数代替内置的open().它允许您定义文件的编码,然后使用给定的编码透明地将内容解码为unicode.
所以当你打电话的时候content = codecs.open("myfile.txt", "r", "utf8").read() content会是unicode.
codecs.open: http://docs.python.org/library/codecs.html?#codecs.open
如果我想念一些东西,请告诉我.
如果你还没有我推荐阅读Joel关于unicode和编码的文章:http: //www.joelonsoftware.com/articles/Unicode.html
| 归档时间: |
|
| 查看次数: |
19481 次 |
| 最近记录: |