关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 转_#!/usr/bin/python coding:utf-8-程序员宅基地

#!/usr/bin/python

是用来说明脚本语言是python的

是要用/usr/bin下面的程序(工具)python,这个解释器,来解释python脚本,来运行python脚本的。

 

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

是用来指定文件编码为utf-8的

详情可以参考:

PEP 0263 — Defining Python Source Code Encodings

 

在此,详细的(主要是翻译)解释一下,为何要加这个编码声明,以及如何添加编码声明:

 

使用文件编码声明以前所遇到的问题

Python 2.1中,想要输入Unicode字符,只能用基于Latin-1的"unicode-escape"的方式输入 -> 对于其他非Latin-1的国家和用户,想要输入Unicode字符,就显得很繁琐,不方便。

希望是:

编程人员,根据自己的喜好和需要,以任意编码方式输入字符串,都可以,这样才正常。

 

建议选用的方案

所以,才有人给Python官方建议,所以才有此PEP 0263。

此建议就是:

允许在Python文件中,通过文件开始处的,放在注释中的,字符串形式的,声明,声明自己的python文件,用何种编码。

由此,需要很多地方做相应的改动,尤其是Python文件的解析器,可以识别此种文件编码声明。

 

具体如何声明python文件编码?

上面已经说了,是,文件开始处的,放在注释中的,字符串形式的,声明。

那具体如何声明,以什么样的格式去声明呢?

其实就是,你之前就见过的,这种:

1

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

对此格式的详细解释是:

  1. 如果没有此文件编码类型的声明,则python默认以ASCII编码去处理
    • 如果你没声明编码,但是文件中又包含非ASCII编码的字符的话,python解析器去解析的python文件,自然就会报错了。
  2. 必须放在python文件的第一行或第二行
  3. 支持的格式,可以有三种:
    1. 带等于号的:

      1

      # coding=<encoding name>

    2. 最常见的,带冒号的(大多数编辑器都可以正确识别的):

      1

      2

      #!/usr/bin/python

      # -*- coding: <encoding name> -*-

    3. vim的:

      1

      2

      #!/usr/bin/python

      # vim: set fileencoding=<encoding name> :

  4. 更加精确的解释是:
    • 符合正则表达式:

      1

      "coding[:=]\s*([-\w.]+)"

    • 的都可以,很明显,如果你熟悉正则表达式,也就可以写出来,其他一些合法的编码声明,以utf-8为例,比如:

      1

      2

      3

      4

      5

      coding:         utf-8

      coding=utf-8

      coding=                  utf-8

      encoding:utf-8

      crifanEncoding=utf-8

  5. 为了照顾特殊的Windows中的带BOM(’\xef\xbb\xbf’)的UTF-8
    1. 如果你的python文件本身编码是带BOM的UTF-8,即文件前三个字节是:’\xef\xbb\xbf’,那么:
      1. 即使你没有声明文件编码,也自动当做是UTF-8的编码
      2. 如果你声明了文件编码,则必须是声明了(和你文件编码本身相一致的)UTF-8
        1. 否则(由于声明的编码和实际编码不一致,自然)会报错

 

文件编码声明的各种例子

针对上面的规则,下面给出各种,合法的,非法的,例子,供参考:

合法的python文件编码声明

  1. 带声明了解释器的,Emacs风格的,(注释中的)文件编码声明
    1. 例子1:

      1

      2

      3

      4

      #!/usr/bin/python

      # -*- coding: latin-1 -*-

      import os, sys

      ...

    2. 例子2:

      1

      2

      3

      4

      #!/usr/bin/python

      # -*- coding: iso-8859-15 -*-

      import os, sys

      ...

    3. 例子3:

      1

      2

      3

      4

      #!/usr/bin/python

      # -*- coding: ascii -*-

      import os, sys

      ...

  2. 不带声明了解释器的,直接用纯文本形式的:

    1

    2

    3

    # This Python file uses the following encoding: utf-8

    import os, sys

    ...

  3. 文本编辑器也可以有多种(其他的)定义编码的方式:

    1

    2

    3

    4

    #!/usr/local/bin/python

    # coding: latin-1

    import os, sys

    ...

    • 很明显,其中的没用-*-,直接用了coding加上编码值
  4. 不带编码声明的,默认当做ASCII处理:

    1

    2

    3

    #!/usr/local/bin/python

    import os, sys

    ...

非法的python文件编码声明举例

  1. 少了coding:前缀

    1

    2

    3

    4

    #!/usr/local/bin/python

    # latin-1

    import os, sys

    ...

  2. 编码声明不在第一行或第二行:

    1

    2

    3

    4

    5

    #!/usr/local/bin/python

    #

    # -*- coding: latin-1 -*-

    import os, sys

    ...

  3. 不支持的,非法的字符编码(字符串)声明:

    1

    2

    3

    4

    #!/usr/local/bin/python

    # -*- coding: utf-42 -*-

    import os, sys

    ...

 

python文件编码声明所遵循的理念

1.单个的完整的python源码文件中,只用单一的编码。

->

不允许嵌入了多种的编码的数据

否则会导致(python解释器去解析你的python文件时)报编码错误。

 

不太懂这段:

Any encoding which allows processing the first two lines in the way indicated above is allowed as source code encoding, this includes ASCII compatible encodings as well as certain multi-byte encodings such as Shift_JIS. It does not include encodings which use two or more bytes for all characters like e.g. UTF-16. The reason for this is to keep the encoding detection algorithm in the tokenizer simple.

 

2.这段也不太懂:

Handling of escape sequences should continue to work as it does now, but with all possible source code encodings, that is standard string literals (both 8-bit and Unicode) are subject to escape sequence expansion while raw string literals only expand a very small subset of escape sequences.

 

3.Python的分词器+编译器,会按照如下的逻辑去工作:

  1. 读取文件
  2. 不同的文件,根据其声明的编码去解析为Unicode
  3. 转换为UTF-8字符串
  4. 针对UTF-8字符串,去分词
  5. 编译之,创建Unicode对象

要注意的是:

Python中的标识符,都是ASCII的。

 

其余的内容,不翻译了。

至此,已经解释的够清楚了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chuanyuanshuo/article/details/88051844

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签