gpt4 book ai didi

python - 在 Windows 上的 Python 2.x 中从命令行参数读取 Unicode 字符

转载 作者:IT老高 更新时间:2023-10-28 22:08:19 25 4
gpt4 key购买 nike

我希望我的 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)

在我为日语代码页设置的 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>

我相信那是 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'

注意——我说的是 Python 2.x,而不是 Python 3.0。我发现 Python 3.0 将 sys.argv 提供为正确的 Unicode。但是现在过渡到 Python 3.0 还为时过早(由于缺乏 3rd 方库支持)。

更新:

一些答案​​说我应该根据 sys.argv 的编码进行解码。问题在于它不是完整的 Unicode,所以有些字符无法表示。

下面是一个让我伤心的用例:我有 enabled drag-and-drop of files onto .py files in Windows Explorer .我的文件名包含各种字符,包括一些不在系统默认代码页中的字符。当字符在当前代码页编码中无法表示时,我的 Python 脚本在所有情况下都无法通过 sys.argv 获得正确的 Unicode 文件名。

当然有一些 Windows API 可以读取带有完整 Unicode 的命令行(Python 3.0 可以做到)。我假设 Python 2.x 解释器没有使用它。

最佳答案

这是我正在寻找的解决方案,调用 Windows GetCommandLineArgvW 函数:
Get sys.argv with Unicode characters under Windows (来自 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()

现在,我使用它的方式很简单:

import sys
import win32_unicode_argv

从那时起,sys.argv 就是一个 Unicode 字符串列表。 Python optparse 模块似乎很乐意解析它,这很棒。

关于python - 在 Windows 上的 Python 2.x 中从命令行参数读取 Unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/846850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com