Python Unicode编码

Mor*_*789 5 python unicode encode argparse

我正在使用argparse读取我的python代码的参数.其中一个输入是文件[ title] 的标题,它可以包含Unicode字符.我一直在22????22用作测试字符串.

我需要将输入的值写入title文件,但是当我尝试将字符串转换为UTF-8它时,总是会抛出错误:

UnicodeDecodeError:'ascii'编解码器无法解码位置2中的字节0x8f:序数不在范围内(128)

我一直在环顾四周,看到我需要我的字符串u"foo"才能调用.encode()它.

当我运行type()我的输入时,argparse我看到:

<type 'str'>
Run Code Online (Sandbox Code Playgroud)

我希望得到一个回应:

<type 'unicode'>
Run Code Online (Sandbox Code Playgroud)

我怎样才能以正确的形式获得它?

理念:

修改argparse以接收a str但将其存储为unicode字符串u"foo":

parser.add_argument(u'title', metavar='T', type=unicode, help='this will be unicode encoded.')
Run Code Online (Sandbox Code Playgroud)

这种方法根本不起作用.思考?

编辑1:

一些示例代码,其中title22????22:

inputs = vars(parser.parse_args())
title = inputs["title"]
print type(title)
print type(u'foo')
title = title.encode('utf8') # This line throws the error
print title
Run Code Online (Sandbox Code Playgroud)

Mec*_*ail 12

看起来您的输入数据是SJIS编码(日语的遗留编码),它在bytestring中的位置2处产生字节0x8f:

>>> '22????22'.encode('sjis')
b'22\x8f\xad\x8f\x97\x8e\x9e\x91\xe322'
Run Code Online (Sandbox Code Playgroud)

(在Python 3提示符下)

现在, 我猜是的 为了"将字符串转换为UTF-8",您使用了类似的东西

title.encode('utf8')
Run Code Online (Sandbox Code Playgroud)

问题是它title实际上是一个包含SJIS编码字符串的字节串.由于Python 2中的设计缺陷,字节串可以直接为encoded,并且它假定字节串是ASCII编码的.所以你所拥有的在概念上等同于

title.decode('ascii').encode('utf8')
Run Code Online (Sandbox Code Playgroud)

当然,decode通话失败了.

在编码为UTF-8之前,您应该从SJIS显式解码为Unicode字符串:

title.decode('sjis').encode('utf8')
Run Code Online (Sandbox Code Playgroud)

正如Mark Tolonen指出的那样,您可能正在键入控制台中的字符,而您的控制台编码是非Unicode编码.

事实证明你的sys.stdin.encodingcp932,这是微软SJIS的变种.为此,请使用

title.decode('cp932').encode('utf8')
Run Code Online (Sandbox Code Playgroud)

你真的应该将你的控制台编码设置为标准的UTF-8,但我不确定这是否可以在Windows上使用.如果这样做,您可以跳过解码/编码步骤,只需将输入字节串写入文件即可.