当前位置: 首页 > 面试题库 >

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

胡昊
2023-03-14
问题内容

我希望我的Python脚本能够在Windows中读取Unicode命令行参数。但是看来sys.argv是用某种本地编码而不是Unicode编码的字符串。如何阅读完整Unicode的命令行?

示例html" target="_blank">代码: 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还为时过早(由于缺乏对第三方库的支持)。

更新:

有几个回答说我应该根据sys.argv编码的内容进行解码。问题在于它不是完整的Unicode,因此某些字符无法表示。

这是让我感到悲伤的用例:我已在Windows资源管理器中将文件拖放到.py文件中。我的文件名带有各种字符,包括某些不在系统默认代码页中的字符。当在当前代码页编码中无法表示字符时,在所有情况下,我的Python脚本都无法通过sys.argv传递正确的Unicode文件名。

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


问题答案:

这是我要寻找的解决方案,它调用WindowsGetCommandLineArgvW函数:
在Windows下从ActiveState获取带有Unicode字符的sys.argv

但是我进行了一些更改,以简化其用法并更好地处理某些用法。这是我用的:

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字符串列表。Pythonoptparse模块似乎很高兴解析它,这很棒。



 类似资料:
  • 12.4.1 os 包 os 包中有一个 string 类型的切片变量 os.Args,用来处理一些基本的命令行参数,它在程序启动后读取命令行输入的参数。来看下面的打招呼程序: 示例 12.11 os_args.go: // os_args.go package main import ( "fmt" "os" "strings" ) func main() {

  • 我总是从命令行运行程序,允许你混合参数的顺序。如果你在其中加入额外的东西,他们就会抓住你。例如: 他们是怎么做到的?有这方面的模块吗?

  • 我想按照他们键入的方式获取用户命令。唯一允许的区别是,可以代替“”,反之亦然。 例如,如果用户键入。 我想在控制台上记录以下内容之一。 但不可接受: 如上所述,引号可以不同于用户提供的引号(可以替换,反之亦然,如第B行),但它们不能放错位置(如第C行和第D行)。希望这是清楚的。 编辑:编辑整个问题以避免混淆。

  • 如果我执行plink命令 当提示输入密码时,我将获得 Sudo:没有tty存在,也没有指定askpass程序 Sudo:3次错误的密码尝试 如何从执行sudo?或者有其他选择吗?

  • 在Windows中,如何访问批处理文件运行时传递的参数? 例如,假设我有一个名为< code>hello.bat的程序。当我在Windows命令行输入< code>hello -a时,如何让我的程序知道< code>-a是作为参数传入的?

  • 问题内容: 我对Java有点陌生,当我将unicode字符串分配给 为什么在两种情况下结果都不同,文件a.txt也包含相同的字符串。但是当我打印文件的输出时,它会打印而不是实际的unicode字符。任何想法,如果我要归档也要作为字符串打印的内容,我该怎么做。 问题答案: 您的代码应该是正确的,但是我想文件“ a.txt”不包含用UTF-8编码的Unicode字符,而是转义的字符串“ \ u0142