【问题标题】:Is '# -*- coding: utf-8 -*-' also a comment in Python?'# -*- coding: utf-8 -*-' 也是 Python 中的注释吗?
【发布时间】:2017-05-31 12:52:06
【问题描述】:

既然我们在 Python 中使用# 来插入 cmets,那么 Python 是如何处理的:

# -*- coding: utf-8 -*-

不同?

【问题讨论】:

  • 这实际上经常发生在软件中。他们实际上对 cme​​ts 进行了一些基本的解析并寻找特定的命令。我想到的另一个例子是 Hypermesh,但我相信还有更多。
  • 您可以将其视为在解析器之前运行的预处理器,解析器会查看文件并决定如何对其进行解码。然后解析器本身启动并跳过该行,因为它是一个注释。一些 unixy 文本编辑器做同样的事情来知道编辑器应该如何打开文件。
  • @Ev.Kounis 也许是最突出的例子:en.wikipedia.org/wiki/Shebang_(Unix)
  • 值得注意的是,就 Python 而言,-*- 部分是完全可选的,但包含它们似乎是习惯性的。 The docs 说它“也被 GNU Emacs 识别”,这表明这就是它的来源(@tdelaney 关于文本编辑器的一个例子),但我已经在代码中看到它(并自己使用它)这是 Emacs 从未接触过的。
  • @MartijnPieters:我明白了! 如果您在 Python 2 上使用 IDLE,并且 if 您的文件包含非 ASCII 字符(如果我添加了版权行,我经常这样做),那么它会提示您可以使用 Emacs -*- 样式添加编码声明。所以我就是从那里拿起它的。

标签: python unicode encoding utf-8 comments


【解决方案1】:

是的,它也是一个评论。 并且如果该注释的内容位于文件的顶部,即前两行,则该注释的内容具有特殊含义。

来自Encoding declarations documentation

如果 Python 脚本的第一行或第二行中的注释与正则表达式coding[=:]\s*([-\w.]+) 匹配,则将此注释作为编码声明处理;该表达式的第一组命名源代码文件的编码。编码声明必须单独出现在一行中。如果是第二行,第一行也必须是注释行。

请注意,就 cmets 而言,应该使用什么编解码器来读取文件并不重要。 Python 通常会忽略# 标记之后的everything,并且在所有接受的源代码编解码器中,#、编码声明和行分隔符的编码完全相同,因为它们都是 ASCII 的超集。所以解析器所要做的就是读取一行,扫描注释中的特殊文本,如果需要读取另一行,扫描注释,然后配置解析器根据给定的编解码器读取数据。

鉴于注释必须是文件中的第一或第二(如果是第二行,第一行也必须是注释),这是完全安全的,因为配置的编解码器只能使无论如何都与非注释行有所不同。

【讨论】:

  • 所以真正的问题变成了:为什么我们使用# -*- coding: X -*- 而不是# coding: X
  • @J.C.Leitão:你不必这样做。 任何与正则表达式匹配的东西 都可以。但是,如果您使用 Emacs 作为编辑器,那么该注释也会通知该编辑器使用什么编解码器。
  • `文件保存为什么编解码器`不应该是what encoding the file is saved as
  • @ShravilPotdar:有很多东西。 Unix 系统使用shebang lineWindows py launcher 将查看相同的信息。如前所述,许多编辑器可以使用 cmets 中的文本进行配置(不仅仅是要使用什么编解码器,还有许多其他方面,请参阅 emacsvim 文档)。可能还有更多。
  • @R.M.:不,不支持多字节编解码器,正因如此。来自PEP 263允许以上述方式处理前两行的任何编码都允许作为源代码编码,这包括与 ASCII 兼容的编码以及某些多字节编码,例如 Shift_JIS。它不包括对所有字符使用两个或更多字节的编码,例如UTF-16。这样做的原因是为了保持标记器中的编码检测算法简单。
【解决方案2】:

请参阅 Python 参考手册中的encoding declarations

如果 Python 脚本的第一行或第二行中的 comment 与正则表达式 coding[=:]\s*([-\w.]+) 匹配,则该 comment 被处理为编码声明;该表达式的第一组命名源代码文件的编码。

(强调我的)

所以是的,这是一个评论,一个特殊的评论。特殊之处在于解析器将尝试对其进行操作,而不是像对待不在第一行或第二行的 cmets 那样忽略它。以示例文件decl.py 中的未注册编码声明为例:

# # -*- coding: unknown-encoding -*-
print("foo")

如果你尝试运行它,Python 会尝试处理它,失败并抱怨:

python decl.py 
  File "decl.py", line 1
SyntaxError: encoding problem: unknown-encoding

【讨论】:

  • 但是,如果您要将unkown-encoding 注册为编码,例如使用.pth 文件,那么实际上会加载并使用该编解码器。这为预解析代码处理提供了一个非常好的和有趣的机会。
  • 确实@MartijnPieters我主要补充说作为Python处理声明的代码示例,而不是对其进行任何其他声明。
  • github.com/dropbox/pyxl 是@MartijnPieters 所指的一个例子。
猜你喜欢
  • 2013-12-16
  • 2014-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 2012-10-27
  • 1970-01-01
相关资源
最近更新 更多