设为首页 收藏本站
查看: 629|回复: 0

[经验分享] [译]如何定义python源文件的文件编码

[复制链接]

尚未签到

发表于 2015-11-30 11:22:22 | 显示全部楼层 |阅读模式
简介
  这篇文章是为了介绍定义python源文件文件编码的方法。python解释器可以根据所指定的编码信息对当前文件进行解析。通常来说,这种方法可以提高解析器对Unicode编码的源文件的识别,并且支持书写Unicode编码,例如在一个支持unicode编码的编辑器中使用UTF-8。
  

问题
  在python2.1中,unicode编码只能通过Latin-1中的“unicode-escape”的方式来实现。这让很多平时不使用Latin-1编码的用户感到非常的不友好,尤其是大多数的亚洲国家更是这样。程序员可以使用他们所习惯的编码来编写8-bit的字符代码,却不得不因为要用到unicode编码而使用"unicode-escape"。
  

解决方法
  我们希望让每一个python文件都可以通过在文件顶端书写一些特定的注释的方法,来实现python源代码编码的可见性和易维护性。
  为了让python能够识别出文件编码的定义,需要做一些列关于对python源文件代码数据的扩充。
  

定义编码
  在没有指定其它编码的情况下,python默认使用ASCII作为标准编码。
  如果想要定义文件代码编码,一个特殊的注释应该放到源文件的第一或第二行,例如:

          # coding=<encoding name>
  或(使用一种大多数编辑器都能够识别的方式)

          #!/usr/bin/python
# -*- coding: <encoding name> -*-

  或

          #!/usr/bin/python
# vim: set fileencoding=<encoding name> :
  恰好,第一或第二行都完全符合正则表达式“coding[:=]\s*([-\w.]+)”。这个表达式获取到的第一组信息就是编码名称。如果python无法识别编码名称,那么将会在编译完成时报错。在python编码定义的行中,严禁出现python的其它声明。
  为了避免一些系统,例如windows,在unicode文件头中增加了文件头标记,UTF-8的签名“\xef\xbb\xbf”同样会作识别文件编码的参照(即使没有设置文件编码注释)。
  如果一个源文件既有UTF-8文件头标记,又用注释声明了文件编码,那么此时仅可以声明成“UTF-8”。其它的编码将会导致错误。
  

示例
  以下示例用语说明使用不同的方法,如何在python文件顶端定义python源文件编码。
  文件:
  1. 利用解释器,并使用Emacs风格的文件编码
  注释:

          #!/usr/bin/python
# -*- coding: latin-1 -*-
import os, sys
...
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import os, sys
...
#!/usr/bin/python
# -*- coding: ascii -*-
import os, sys
...
  2. 不使用解释器,使用一段文字描述

          # This Python file uses the following encoding: utf-8
import os, sys
...

  3. 文本编辑器中,可以有不同的方式来定义文件的编码,例如:

          #!/usr/local/bin/python
# coding: latin-1
import os, sys
...

  4. 不使用编码注释,python解释器会将文件当成是ASCII:

          #!/usr/local/bin/python
import os, sys
...

  5. 不会生效的编码注释:
  遗失了“coding:”前缀:

          #!/usr/local/bin/python
# latin-1
import os, sys
...
  编码注释不在第一和第二行:

          #!/usr/local/bin/python
#
# -*- coding: latin-1 -*-
import os, sys
...
  不支持的编码:

          #!/usr/local/bin/python
# -*- coding: utf-42 -*-
import os, sys
...
理念
  我们是根据以下理念来实现的编码注释的用法:
  1. 一个python源文件应该具有唯一的编码。内部混杂多种编码数据的行为是不被允许的,并且在编译时会报错。
  任意一个能够识别出源码前两行,并且符合以上讨论的编码,都可以作为源码文件的编码,包括ASCII兼容编码和某些多字节编码,如Shift_JIS。所有字符都使用至少两个字节的编码无法被识别,例如UTF-16。这是为了让编码检测算法的检测功能更加简洁。
  2. 对于未定义的信息,应该什么都不处理而继续进行分析,就像当前的行为一样。其实所有的可用编码值,都是标准的字符串字符(都是8-bit的Unicode),它们对于其它可能出现在代码中的未定义的信息来说只是很小的一部分。
  3. python的 tokenizer/compiler 组件应该被更新为一下的工作流程:
      a)读取文件
      b)将文件解码成Unicode编码,即一个固定的、假设的编码
      c)将文件转换为UTF-8字节字符串
      d)tokenize UTF-8化的内容
  e)编译,根据给定的Unicode数据创建Unicode对象 ,并且根据文件中给定的编码将UTF-8数据重编码成新的8-bit字符串数据。
  注意,python的识别码被限制为了ASCII编码集合,所以在步骤d后不用再对它进行额外的转换。
  

向下兼容
  为了兼容已存在的,没有使用ASCII编码并且没有声明编码格式的,现在需要进行2步来进行使用:
  1. 将所有不使用ASCII编码并且没有做注释的文件,将它们当作丢失了“iso-8859-1”定义。这会导致强行将字节字符串的处理放置到步骤2-5之前,并且在python2.2中,提升了对非ASCII字符——Unicode的兼容。
      当发现输入文件没有ASCII字节时,会在编码输入文件的时候产生一个警告。
      2. 删除警告,并将默认编码格式设置为“ASCII”。
      内建compile() API,用来提高对输入文件为Unicode编码时的处理能力。字节字符串的输入的处理方式在上文中已经进行过描述。
      如果一个带有编码声明的字符串传递给了compile(),那么将会发生一个SyntaxError。
      SUZUKI Hisao可以通过使用patch来兼容,查看[2]获取更多信息。
      只有在第一步可以使用的patch,在[1]。
  

新进展
  向下兼容中的步骤1和2已经在2.3版本中进行了完善,除了将默认编码置为“ascii”。
  在2.5版本中,实现了将默认编码设置成“ascii”。
  



链接

    [1] Phase 1 implementation:
http://python.org/sf/526840
[2] Phase 2 implementation:
http://python.org/sf/534304

历史

    1.10 and above: see CVS history
1.8: Added '.' to the coding RE.
1.7: Added warnings to phase 1 implementation. Replaced the
Latin-1 default encoding with the interpreter's default
encoding. Added tweaks to compile().
1.4 - 1.6: Minor tweaks
1.3: Worked in comments by Martin v. Loewis:
UTF-8 BOM mark detection, Emacs style magic comment,
two phase approach to the implementation

版权

    This document has been placed in the public domain.


  Source: https://hg.python.org/peps/file/tip/pep-0263.txt
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-145314-1-1.html 上篇帖子: 创业公司都在使用的3款Python库 下篇帖子: python 网络编程——客户端
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表