【问题标题】:Lost with encodings (shell and accents)丢失编码(外壳和口音)
【发布时间】:2011-12-21 00:21:53
【问题描述】:

我遇到了编码问题。 我正在使用版本

Python 2.7.2+(默认,2011 年 10 月 4 日,20:03:08) [GCC 4.6.1] 在 linux2 上

我有带有 é à 等重音的字符。 我的脚本使用 utf-8 编码

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

用户可以使用 raw_input() 和 .

键入字符串
def rlinput(prompt, prefill=''):
    readline.set_startup_hook(lambda: readline.insert_text( prefill))
    try:
        return raw_input(prompt)
    finally:
        readline.set_startup_hook()

在主循环“伪”shell中调用

while to_continue : 
    to_continue, feedback = action( unicode(rlinput(u'todo > '),'utf-8') )
    os.system('clear')
    print T, u"\n" + feedback

数据以pickle形式存储在文件中。

我设法让应用程序正常运行,但最终得到了一些愚蠢的东西,例如

核心文件:

class Task()
...
def __str__(self):
    r = (u"OK" if self._done else u"A faire").ljust(8) + self.getDesc()
    return r.encode('utf-8')

等等在shell文件中:

feedback = jaune + str(t).decode('utf-8') + vert + u" supprimée"

这就是我意识到编码/解码可能完全错误的地方。 所以我尝试直接在 rlinput 中解码但失败了。 我在stackoverflow中阅读了一些帖子,重新阅读http://docs.python.org/library/codecs.html 等待我的python书,我迷路了:/

我想有很多错误的代码,但我这里的问题只与编码问题有关。 您可以在此处找到代码:(大多数法语 cmets,抱歉,这是供个人使用的,我是初学者,您还需要 yapsy - http://yapsy.sourceforge.net/)(然后配置路径,然后在 py_todo 中:./todo_shell.py ) : http://bit.ly/rzp9Jm

【问题讨论】:

  • 明确一点:您到底想实现什么?或者换句话说,为什么尝试 "to decode directly in rlinput" 失败了?您能否陈述一个用例来描述您的操作及其预期输出?在您当前的帖子中,我真的找不到要回答的问题...
  • @jro :raw_input 没问题,结果设置为 var。显示输入内容时出现错误:像这样:UnicodeDecodeError:'ascii'编解码器无法解码位置 10 的字节 0xc3:序数不在范围内(128)。我知道我可以修复它,但我更像是“我应该解码用户输入,在 var 设置时间()解码等”@eryksun:我今晚会挖掘它,谢谢
  • @eryksun:我刚刚实现了 unicode 方法:现在一切正常!谢谢

标签: python shell encoding diacritics


【解决方案1】:

正如@wberry 建议的那样,我检查了编码:好的

$ file --mime-encoding todo_shell.py task.py todo.py
todo_shell.py: utf-8
task.py:       utf-8
todo.py:       utf-8
$ echo $LANG
fr_FR.UTF-8
$ python -c "import sys; print sys.stdin.encoding"
UTF-8

正如@eryksun 建议的解码用户输入(+编码之前提交的字符串)(如果我的记忆好,解决了一些问题)(稍后将深入测试):

def rlinput(prompt, prefill=''):
readline.set_startup_hook(lambda: readline.insert_text( prefill.encode(sys.stdin.encoding) ))
try:
    return raw_input( prompt ).decode( sys.stdin.encoding )
finally:
    readline.set_startup_hook()

我仍然有问题,但我的问题没有明确定义,所以我无法得到明确的答案。 我现在感觉不那么迷失了,并且有方向可以搜索。 谢谢!

编辑:我用 unicode 替换了 str 方法,它杀死了一些(全部?)问题。

感谢@eryksun 的提示。 (这个链接帮助了我:Python __str__ versus __unicode__

【讨论】:

    【解决方案2】:

    标准输入和输出在所有 Unix 系统上都是基于字节的。这就是为什么你必须调用unicode 函数来获取它们的字符串。解码错误表示传入的字节不是有效的 UTF-8。

    基本上,问题在于 UTF-8 编码的假设,这是无法保证的。通过将unicode 调用中的编码更改为'ISO-8859-1',或将终端仿真器的字符编码更改为UTF-8 来确认这一点。 (Putty 支持这一点,在“翻译”菜单中。)

    如果上述实验证实了这一点,您的挑战是支持用户的语言环境并推断出正确的编码,或者可能让用户在命令行参数或配置中声明编码。 $LANG 环境变量是您在没有显式声明的情况下可以做到的最好的环境变量,我发现它不能很好地指示所需的字符编码。

    【讨论】:

    • 我现在登录 Linux 服务器,终端的字符编码设置为 UTF-8。但是os.environ['LANG']'en_US',因此sys.stdin.encoding'ISO-8859-1',这是错误的。如果我输入文本,并依靠sys.stdin.encoding 来解码字节,我会误解数据。
    • 也就是说,我不确定 GNU readline 没有在幕后做与编码相关的事情。也许是这样,在这种情况下,我的回答可能根本不适用。
    • 您不应该将流编码设置为UTF-8吗?手动解码不总是错误的答案吗?
    • 确实如此;我检查了the code。我没想到环境的配置与终端不同。有没有办法查询终端自动设置LANG?我主要使用 Windows——它有一系列不同的问题。
    • @eryksun:我总是将输入和输出编码设置为 UTF-8。如果他们不想这样,他们可以使用iconv。我鄙视使用重定向或由不同用户运行时行为不同的程序。它们本质上是破碎的。 Python 的编码猜谜游戏在@ss 中很痛苦。每次只需将其设置为 UTF-8 即可获得确定性和可预测的行为。可以这么说,让他们来找你。
    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    相关资源
    最近更新 更多