#!/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的。

其余的内容,不翻译了。

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

 
原文链接:http://www.crifan.com/python_head_meaning_for_usr_bin_python_coding_utf-8/

关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 转的更多相关文章

  1. Python脚本开头两行:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用

    转于:https://www.crifan.com/python_head_meaning_for_usr_bin_python_coding_utf-8/ 出处:在路上 一.基本功能 1)#!/us ...

  2. Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用

    #!/usr/bin/Python指定用什么解释器运行脚本以及解释器所在的位置 # -*- coding: utf-8 -*-用来指定文件编码为utf-8的 估计有不少人注意过一些python脚本开头 ...

  3. 关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型

    #!/usr/bin/python指定用什么解释器运行脚本以及解释器所在的位置 # -*- coding: utf-8 -*-用来指定文件编码为utf-8的PEP 0263 -- Defining P ...

  4. 【转】关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型

    原文网址:http://www.crifan.com/python_head_meaning_for_usr_bin_python_coding_utf-8/ #!/usr/bin/python 是用 ...

  5. 【转载】关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型

    1.#!/usr/bin/python 是用来说明脚本语言是 python 的 是要用 /usr/bin下面的程序(工具)python,这个解释器,来解释 python 脚本,来运行 python 脚 ...

  6. (二)Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用

    #!usr/bin/env python # -*- coding: utf-8 -*- def test(): print('hello, world') if __name__ == " ...

  7. 关于python脚本头部设置#!/usr/bin/python

    今天又是贼几把菜的一天0.0 读别人程序的时候看到在python文件头部设置签名,感觉贼几把酷,自己也试着在文件前段设置了一下. 设置还是蛮简单的,设置过程如图所示. 设置后如图所示: 当然你也可能看 ...

  8. #!/usr/bin/env python与#!/usr/bin/python的区别

    [摘自:http://blog.csdn.net/wh_19910525/article/details/8040494] 一般的python文件的开头都有#!/usr/bin/python.这是什么 ...

  9. Python程序 #!/usr/bin/python 的解释

    关于脚本第一行的 #!/usr/bin/python 的解释,相信很多不熟悉 Linux 系统的同学需要普及这个知识,脚本语言的第一行,只对 Linux/Unix 用户适用,用来指定本脚本用什么解释器 ...

随机推荐

  1. Python 迭代器与生成器及装饰器

    1.迭代器(Iterator) 迭代器是访问集合元素的一种方式.有下面特点: 1)每次调用__next__()方法只访问一个元素,而且不能后退,便于循环比较大的数据集合,节省内存:(当容器中没有可访问 ...

  2. Vue的组件及传参

    目录 Vue的组件及传参 Vue组件的概念 根组件 子组件(局部组件) 父组件向子组件传值 子组件向父组件传值 Vue的组件及传参 Vue组件的概念 我们首先要知道组件的概念,实际上每一个组件都是一个 ...

  3. java_迭代器

    java的迭代器(Iterator): 一个可迭代的对象调用iterator可以得到一个迭代器对象 HasNext:判断是否还有下一个元素 next:返回迭代的元素 步骤: public static ...

  4. C开发系列-字符串

    C语言字符串 C语言字符串本质是使用字符数组来存储的. #include <stdio.h> int main() { "jake"; // "jake&qu ...

  5. 确认(confirm 消息对话框)语法:confirm(str); 消息对话框通常用于允许用户做选择的动作,如:“你对吗?”等。弹出对话框(包括一个确定按钮和一个取消按钮)

    确认(confirm 消息对话框) confirm 消息对话框通常用于允许用户做选择的动作,如:"你对吗?"等.弹出对话框(包括一个确定按钮和一个取消按钮). 语法: confir ...

  6. JavaScript特效源码(8、其他特效)

    1.中文日期 中文日期[无须修改][共1步]] ====1.将以下代码加入HEML的<body></body>之间 <script LANGUAGE="Java ...

  7. PyTorch中的C++扩展

    今天要聊聊用 PyTorch 进行 C++ 扩展. 在正式开始前,我们需要了解 PyTorch 如何自定义module.这其中,最常见的就是在 python 中继承torch.nn.Module,用 ...

  8. gdb调试工具的使用

    GDB是一个由GNU开源组织发布的.UNIX/LINUX操作系统下的.基于命令行的.功能强大的程序调试工具. GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调 ...

  9. [JZOJ3177] 【GDOI2013模拟5】安全监控

    题目 描述 (样例都懒得发出来了) 题目大意 给你一个有向图,从111号点出发,绕一圈回来.这一圈中必须经过222号点. 问经过的最少的点数(不重复). 思考历程 一看就觉得是一道神题. 然后仔细观察 ...

  10. Python-数据类型内置方法(1)

    目录 数字类型内置方法 整形(int) 浮点型(float) 字符串类型内置方法 优先掌握 需要掌握 了解 列表类型内置方法 优先掌握 需要掌握 数字类型内置方法 整形(int) 作用:年龄 定义:x ...