【问题标题】:How can strings with non-ASCII characters be retrieved with OptParse?如何使用 OptParse 检索具有非 ASCII 字符的字符串?
【发布时间】:2012-10-29 12:48:53
【问题描述】:

我正在使用OptParse 模块来检索字符串值。 OptParse only supports str typed strings,不是unicode

假设我的脚本开始于:

./someScript --some-option ééééé

法文字符,如'é',正在输入str,读入代码时触发UnicodeDecodeErrors:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 99: ordinal not in range(128)

我使用了 unicode 内置函数,但要么出现错误,要么字符消失:

>>> unicode('é');
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
>>> unicode('é', errors='ignore');
u''

我可以做些什么来使用OptParse 来检索unicode/utf-8 字符串?

更新

似乎可以检索并打印该字符串,但随后我尝试将该字符串与 sqlite 一起使用(使用 APSW 模块),并尝试使用cursor.execute("...") 以某种方式转换为unicode,然后出现错误.

这是一个导致错误的示例程序:

#!/usr/bin/python
# coding: utf-8

import os, sys, optparse
parser = optparse.OptionParser()
parser.add_option("--some-option")
(opts, args) = parser.parse_args()
print unicode(opts.some_option)

【问题讨论】:

  • Str 对象只是字节存储,因此如果输入是 UTF-8,则字符串将保存 UTF-8 值。哪里抛出了 unicode 错误?
  • 我刚刚在 UTF-8 控制台上对此进行了测试,optparse 工作正常并将字符返回到控制台。你能澄清一下这个错误是在你的代码中还是在 optparse 中?
  • 取决于您的程序在 optparse 上还是从头开始构建?在这种情况下,我会推荐 docopts 包而不是 optparse。你会真的很惊讶它解析 cli 参数是多么容易。
  • @Fuzzyfelt:感谢您的第二条评论,我的问题范围缩小了一点。

标签: python unicode ascii


【解决方案1】:

您可以在解析器处理参数之前对其进行解码。以你为例:

#!/usr/bin/python
# coding: utf-8
import os, sys, optparse
parser = optparse.OptionParser()
parser.add_option("--some-option")

# Decode the command line arguments to unicode
for i, a in enumerate(sys.argv):
    sys.argv[i] = a.decode('ISO-8859-15')

(opts, args) = parser.parse_args()
print type(opts.some_option), opts.some_option

这给出了以下输出:

C:\workspace>python file.py --some-option préférer
<type 'unicode'> préférer

我选择了ISO/IEC 8859-15 代码页,因为它似乎最适合您。根据需要进行调整。

【讨论】:

  • 为避免硬编码编码,您可以尝试这样猜测:locale.getpreferredencoding() (import locale)。
  • 顺便说一下,你可能需要用unicode(a.decode("your_encoding_here"))使它成为unicode。
【解决方案2】:

输入以控制台编码返回,因此根据您更新的示例,使用:

print opts.some_option.decode(sys.stdin.encoding)

unicode(opts.some_option) 默认使用ascii 作为编码。

【讨论】:

    【解决方案3】:

    我相信你的错误与following有关:

    例如,编写包含欧元货币的 Unicode 文字 符号,可以使用 ISO-8859-15 编码,带欧元符号 具有序数值 164。此脚本将打印值 8364 (对应于欧元符号的 Unicode 代码点),然后 退出:

    # -*- coding: iso-8859-15 -*-
    
    currency = u"€"
    print ord(currency)
    

    【讨论】:

      【解决方案4】:
      #!/usr/bin/python
      # coding: utf-8
      
      import os, sys, optparse
      
      reload(sys)
      sys.setdefaultencoding('utf-8')
      
      parser = optparse.OptionParser()
      parser.add_option(u"--some-option")
      (opts, args) = parser.parse_args()
      print opts.print_help()
      

      【讨论】:

      • 这似乎对我不起作用。你用的是python 2还是3?我正在运行 python 2.7。
      猜你喜欢
      • 1970-01-01
      • 2016-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 2014-04-22
      • 2013-05-27
      相关资源
      最近更新 更多