【问题标题】:Weird UTF-8 one-liner interpreter bug奇怪的 UTF-8 单行解释器错误
【发布时间】:2017-02-21 15:31:00
【问题描述】:

所以,我对这个程序有这种可憎的憎恶:

print((lambda raw, name_file: ((lambda start_time, total, lines, names: ((lambda parsed: ('\n'.join(str(10*(parsed[0][name]+parsed[1][name]/2)/total).ljust(6) + name for name in names)))(list(map(lambda x: __import__("collections").Counter(x), map(lambda x: list(map(lambda x: x[1], x)), [list(group[1]) for group in __import__("itertools").groupby(sorted([list(group[1])[0] for group in __import__("itertools").groupby(sorted(list(map(lambda x: [x[3], ' '.join([x[4], x[5], x[6]]), __import__("datetime").datetime.strptime(x[0] + ' ' + x[1], '%Y.%m.%d %H:%M:%S')], map(str.split, filter(lambda x: (any(name.strip() in x for name in names) and "OK ( 0 )" in x), lines))))), lambda x: (x[0], x[1]))], key = lambda x: (x[2], x[1], x[0])), lambda x: ((x[2] < start_time+__import__("datetime").timedelta(days=7)) + (x[2] < start_time+__import__("datetime").timedelta(days=14))))]))))))(__import__("datetime").datetime.strptime(raw.readline().strip(), '%d.%m.%Y %H:%M'), int(raw.readline()), map(lambda x: x.replace("Минчен", ""), raw.readlines()), list(map(str.strip, name_file.readlines())))))(raw = open("test.txt", "r"), name_file = open("names.txt", "r")))

(在pastebin 上可能更好)

几乎可以工作,但是它工作的方式很奇怪,对我来说就像一个解释器错误。

现在,代码中唯一的非 ASCII 字符在最后的字符串“Минчен”中,即使这样它们也完全兼容 UTF-8,这应该是默认编码。现在,问题是,Python 抛出了这个错误:

Non-UTF-8 code starting with '\xd1' in file lulz.py on line 1, but no encoding declared;

这不仅仅是一些奇怪的编码问题!如果我删除字符串中的最后一个“н”,程序运行得很好;当我在其位置添加 any 俄语字母时,解释器崩溃了。即使我只在这个地方之前添加一个换行符,任何地方,只要这个字符串在源代码的第二行,解释器就不会崩溃。

当然,我不能提供一个 Minimal 的例子,因为这是多么的挑剔和不稳定,但我很确定这不是预期的行为。这是解释器中的错误还是我做错了什么?

顺便说一句,它可能需要存在“names.txt”和“test.txt”;如果你想测试,你可以用这些名字创建两个空文件。

UPD 即使在任何单个( 之后添加一个空格 也能正常工作!这里肯定有问题。

UPD2我使用的是 Python 3.5.1

>>> python3 --version Python 3.5.1

UPD3这是我的file.

UPD4,这是一个十六进制转储:http://pastebin.com/5R1rbtc3

UPD5 显然,这个问题只能在 Mac 上重现。我觉得不同平台上的不同行为不是故意的。

【问题讨论】:

  • 你能用看起来不像 Lisp 的代码重现这个吗?
  • @chepner 这就是问题所在——几乎任何更改都会破坏该错误!我正在尝试,但我不确定我是否可以
  • 使用从 dropmefile 下载的文件:使用 Python 3.4.4 脚本抱怨找不到 test.txt。使用 Python 2 它抱怨编码,添加一个“编码”声明使它抱怨找不到 test.txt
  • @Tryph test.txt 和 names.txt 都可以为空;你能创建它们然后再试一次吗?
  • 我收到了ValueError: time data '' does not match format '%d.%m.%Y %H:%M'

标签: python python-3.x utf-8 character-encoding


【解决方案1】:

字符本身没有编码 - 说字符是 UTF-8 是没有意义的。 UTF-8 只是可用于表示字符的众多编码之一。您的程序中确实有非 ASCII 字符,并且根据错误,源文件正在以 UTF-8 以外的编码保存。由于源文件中没有声明非UTF-8编码,Python不知道用什么编码代替UTF-8,导致报错。最好的解决方案是告诉您的编辑器使用 UTF-8 保存文件,但显然这样做的过程将特定于您的编辑器。

【讨论】:

  • 而改变我的字符串的长度将如何影响保存文件的编码?不,我确定文件是以 UTF-8 保存的
  • 顺便说一句,使用此答案stackoverflow.com/a/11021413/3713926 中提到的 iconv 方法,我得到该文件绝对是有效的 UTF-8
  • 我已尽我所能回答您提供的信息。如果没有源文件本身,我无法确定问题出在源文件中还是在 Python 中。
  • 也许可以尝试将导致错误的文件的十六进制转储放入 pastebin?
  • 我已经发布了文件本身;我将添加 hexdump
【解决方案2】:

错误在于您对默认源文件编码的期望。 当您使用 Python 3.x 时,它只是 UTF-8(我检查过,3.5 可以毫无问题地解析可憎)

Python 2.x 默认为 ASCII,所以添加一个编码注释作为这个可恶的第一行,你很高兴

# -*- coding: utf8 -*-

【讨论】:

  • -*- 不是必须的
  • 而且,正如“python-3.x”标签所暗示的那样,我确实在使用 python 3.5。另外,如果我使用的是 python 2,程序将根本无法运行,不仅仅是在某些情况下
  • shrug 那么我不知道你在做什么错,我下载了(!不是复制粘贴!)文件并直接用 python 3.5 运行它,没有错误。它必须是你的编辑器,因为你说只编辑一个空格就会出错。我用 sublime text 3 编辑了文件以插入编码行,然后它在 python 2.x 中也能正常工作。
  • @IrmendeJong Umm.. 你在 Linux 上吗?因为我使用的是 Mac;也许有一些平台差异?
  • 我在 Windows 7 上。我从 pastebin 下载了文件。很快将在 mac 上试用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 1970-01-01
相关资源
最近更新 更多