我在Python 2中试过这段代码:
def NewFunction():
return '£'
但我收到一条错误消息,内容如下:
SyntaxError: Non-ASCII character '\xa3' in file '...' but no encoding declared;
see http://www.python.org/peps/pep-0263.html for details
类似地,在Python 3中,如果我编写相同的代码并使用Latin-1编码保存它,则会得到:
SyntaxError: Non-UTF-8 code starting with '\xa3' in file ... on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
如何在代码中的字符串常量中使用磅号?
7条答案
按热度按时间vddsk6oq1#
我建议阅读错误代码提供的PEP。问题是您的代码尝试使用ASCII编码,但磅符号不是ASCII字符。请尝试使用UTF-8编码。您可以从将
# -*- coding: utf-8 -*-
放在.py文件的顶部开始。要获得更高级的功能,您还可以在代码中逐个字符串地定义编码。然而,如果你想在代码中加入磅号文字,你需要一个编码来支持整个文件。4ktjp1zp2#
在我的.py脚本顶部添加以下两行对我来说很有效(第一行是必需的):
nzk0hqpo3#
首先将
# -*- coding: utf-8 -*-
行添加到文件的开头,然后对所有非ASCII unicode数据使用u'foo'
:或者使用自Python 2.6以来的魔法使其自动化:
axr492tv4#
错误消息会告诉你到底出了什么问题,Python解释器需要知道非ASCII字符的编码。
如果要返回U+00A3,则可以说
它通过Unicode转义序列在纯ASCII中表示该字符。如果要返回包含文本字节0xA 3的字节串,则
(在Python 2中,
b
是隐式的;但是显式优于隐式)。错误消息中链接的PEP * 确切地 * 指导您如何告诉Python“这个文件不是纯ASCII;这是我使用的编码”。如果编码是UTF-8,则为
还是兼容Emacs的
如果你不知道你的编辑器使用哪种编码来保存这个文件,你可以用十六进制编辑器或者谷歌搜索来检查一下。Stack Overflow character-encoding标签有一个tag info page,里面有更多的信息和一些故障排除技巧。
用这么多的话来说,在7位ASCII范围(0x 00 - 0x 7 F)之外,Python不能也不应该猜测一个字节序列代表什么字符串。https://tripleee.github.io/8bit#a3显示了字节0xA 3的21种可能的解释,而这只是来自传统的8位编码;但它也可以是多字节编码的第一个字节。但实际上,我猜您实际上使用的是Latin-1,所以您应该
作为源文件的第一行或第二行。无论如何,如果不知道字节应该代表哪个字符,人类也不可能猜到这一点。
注意:
coding: latin-1
肯定会删 debugging 误消息(因为没有字节序列,这在技术上是不允许的),但如果实际编码是其他的,那么在解释代码时可能会产生完全错误的结果。在声明编码时,您必须完全确定地知道文件的编码。vuv7lop35#
在脚本中添加以下两行代码为我解决了这个问题。
希望能有所帮助!
gz5pxeao6#
您可能正在尝试使用Python 2解释器来运行Python 3文件。目前(截至2019年),在Windows和大多数Linux发行版上,当两个版本都安装时,
python
命令默认为Python 2。但是如果你确实在使用Python 2脚本,本页还没有提到的解决方案是以UTF-8+BOM编码重新保存文件,这将在文件的开头添加三个特殊字节,它们将显式地通知Python解释器(和文本编辑器)有关文件编码的信息。
b1payxdu7#
总结
如果出现这个错误,使用一个 coding declaration 来告诉Python源代码(.py)文件的编码,没有这样的声明,Python 3.x将默认为UTF-8;Python 2.x将默认为ASCII。声明看起来像一个注解,包含一个标签
coding:
,后面跟着一个有效文本编码的名称。所有ASCII透明的编码都被支持。例如:
确保文件实际使用的编码以便编写正确的编码声明。有关提示,请参阅How to determine the encoding of text。或者,通过检查文本编辑器中的配置选项,尝试使用不同的编码。
问题
Every file on a computer is composed of raw bytes,即使文件是“以文本模式”打开的,也不是固有的“文本”。当文件应该表示文本(例如Python程序的源代码)时,需要根据 * 编码 * 规则来解释它,以便理解数据。
但是,没有一种明显的方法可以从文件外部指示Python源文件的编码-例如,
import
语法不提供写入编码名称的位置(毕竟,它不一定是从源文件导入的)。因此,编码必须由文件内容本身以某种方式描述,Python需要一种方法来动态地确定这种编码。为了让这个过程以一种一致和可靠的方式工作,Python从2.3版本开始,使用一个简单的引导过程来确定文件编码,这个过程被描述为by PEP 263:
0xEF 0xBB 0xBF
--那么Python会丢弃这些字节,并指出文件的其余部分应该是UTF-8(以这种方式编写的文件有时被称为“utf-8-sig”编码)。Python检测到使用以下正则表达式的编码声明:
这个它旨在匹配其他工具(如Vim和Emacs文本编辑器)已经使用的几个标准编码声明。
编码声明的语法也被设计成只需要能用ASCII表示的字符。因此,任何“ASCII透明”编码都可以使用。默认编码也是ASCII透明的;因此,如果前两行包含编码声明,那么它将被正确读取,如果没有,那么相同的(默认)编码将被用于文件的其余部分。净效果是,就好像一直都假设了正确的编码,即使它不知道是从哪里开始的。聪明吧?
但是,请注意UTF-16和其他非ASCII透明编码不受支持。在此类编码中,编码声明无法使用默认编码读取,因此不会被处理。字节顺序标记也不能用于通知UTF-16:就是不承认,好像原来有计划支持这个,但是放弃了。
Python 3.x
PEP 3120将默认编码更改为UTF-8。因此,源文件can simply be saved with UTF-8 encoding, contain arbitrary text according to the Unicode standard and be used without an encoding declaration.plain ASCII数据也是有效的UTF-8数据,所以仍然没有问题。
如果源代码必须使用 * 不同的 * ASCII透明编码(如Latin-1(ISO-8859-1)或Shift-JIS)进行解释,请使用编码声明。例如:
Python 2.x
默认编码为ASCII。因此,在源文件中写入任何非ASCII文本(如
£
)时,需要编码声明。注意,在Python 2.x中使用Unicode文本仍然需要Unicode常量,而不管源编码。指定编码可以允许Python 2.x将
'ÿ'
解释为有效的源代码(并且为Latin-1输入正确地指定Latin-1而不是UTF-8,可以允许它将该文本视为ÿ
而不是ÿ
),但它仍然是一个 byte 文本(不幸的是,它被称为str
)。要创建一个实际的Unicode字符串,请确保使用u
前缀或适当的“future import”:from __future__ import unicode_literals
.(But然后,为了使这样的字符串可打印,可能仍然需要do even more,especially on Windows;Python 3自动修复了所有这些问题,对于那些因为厌恶显式指定编码而坚持使用古老的、不受支持的版本的人来说:请重新考虑。“显式比隐式好”。从长远来看,3. x的方式要容易得多,也更令人愉快。)
其他解决方法
无论编码如何,Unicode转义都可以用于在字符串文本中包含任意Unicode字符:
无论源文件选择了什么编码,也无论是否声明了它(因为这个文本也是有效的ASCII和UTF-8),它都应该打印lowercase o with a line through it、Chinese hanzi/Japanese kanji表示“snake”和foot emoji(当然,假设您的终端支持这些字符)。
但是,此不能用于标识符名称:
以这种方式报告错误是因为反斜杠(在带引号的字符串之外)是行继续符,并且它后面的所有内容都是非法的。