关于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

智能推荐

Linux进程同步之POSIX信号量_每个进程都要初始化信号量吗-程序员宅基地

文章浏览阅读1k次。部分内容来自:http://blog.csdn.net/anonymalias/article/details/9219945一、概述POSIX信号量有两种:有名信号量和无名信号量,无名信号量也被称作基于内存的信号量。有名信号量通过IPC(Inter-Process Communication,进程间通信)名字进行进程间的同步,而无名信号量如果不是放在进程间的共享内存区中,是不能用来进_每个进程都要初始化信号量吗

Windows 7修改路由表的跃点数_route add 跃点数-程序员宅基地

文章浏览阅读1.8w次。显示当前网关:route printnetstat -r //两个命令都是显示所有的路由表route print -4 //只显示IPV4的网关route print -6 //只显示IPV6的网关添加网关:route add 0.0.0.0 mask 0.0.0.0 192.168.1.1删除网关:route delete 0.0.0.0 mask 0.0.0.0 192.168.1.1修改静态..._route add 跃点数

CCKS2020 任务三 面向中文电子病历的医疗实体及事件抽取_ccks2020数据集医学-程序员宅基地

文章浏览阅读1.9k次。CCKS2020 任务三 本任务是CCKS围绕中文电子病历语义化开展的系列评测的一个延续,在CCKS 2017,2018, 2019相关评测任务的基础上进行了延伸和拓展。 本任务包括两个子任务: (1) 医疗命名实体识别:于给定的一组电子病历纯文本文档,识别并抽取出与医学临床相关的..._ccks2020数据集医学

Failed to resolve: com.android.support.constraint:constraint-layout:1.0.2-程序员宅基地

文章浏览阅读5.7k次。Failed to resolve: com.android.support.constraint:constraint-layout:1.0.2 Install repository and sync project. Show in file. Show in project structure dialog. 未能解决:com.android.support.const_com.android.support.constraint:constraint-layout:1.0.2 jar

MongoDB副本集(一主一备+仲裁)环境部署_mongdb4.0.15 副本集 1个primary +1个 secondary +1个arbite-程序员宅基地

文章浏览阅读3k次。MongoDB复制集是一个带有故障转移的主从集群。是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复。MongoDB复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举产生一个主结点。该主结点被称为primary,一个或多个从结点被称为secondaries。primary结点基本上就是master结点,不同之处在于primary结点在不同时间可能是不同的服务器。如果当前的主结点失效了,复制集中的其余结点将会试图选出一个新的主结点。MongoDB提供了两种复制部署方案:主从复制_mongdb4.0.15 副本集 1个primary +1个 secondary +1个arbiter(仲裁者)

问题:Element-ui中DateTimePicker设置了default-time和picker-options(时间选择范围)后无法选择当天日期_el-date-picker 不能选择当天时间-程序员宅基地

文章浏览阅读3.3k次。一、问题描述  在设置完default-time及picker-options两个属性后,当选择当天时间时,无法选中填入时间!!<el-date-picker v-model="dateTime" unlink-panels value-format="yyyy-MM-dd HH:mm:ss" type="daterange" range-separator="~" start-placeholder="开始日期" _el-date-picker 不能选择当天时间

随便推点

IDEA修改Maven全局配置-程序员宅基地

文章浏览阅读893次。在使用过程中发现,IDEA每次新建一个Project ,这个maven配置都会初始化默认的。这里需要设置下全局配置;File -> Other Settings -> Settings for New Projects...这里设置下即可。参考:https://blog.csdn.net/Suyebiubiu/article/details/85..._idea2.1 maven全局设置

mac phpstorm过期_mac. phpstorm怎么看到期时间-程序员宅基地

文章浏览阅读1.2k次。http://idea.lanyus.com/_mac. phpstorm怎么看到期时间

2010 年一月联考逻辑真题-程序员宅基地

文章浏览阅读314次。2010 年一月联考逻辑真题真题(2010-26)-假言命题推理规则和选言命题的矛盾26.针对威胁人类健康的甲型 H1N1 流感,研究人员研制出了相应的疫苗,尽管这些疫苗是有效的,但某大学研究人员发现,阿司匹林、羟苯基乙酰胺等抑制某些酶的药物会影响疫苗的效果,这位研究员指出:“如果你服用了阿司匹林或者乙酰氨基酚,那么你注射疫苗后就必然不会产生良好的抗体反映。” 如果小张注射疫苗后产生了良好的抗体反映,那么根据上述研究结果可以得出以下哪项结论?A.小张服用了阿司匹林,但没有服用乙酰氨基酚。B.小张没有

【转载】struct dirent 和 DIR结构体 详解-程序员宅基地

文章浏览阅读356次。原文地址:https://blog.csdn.net/sin0803/article/details/375393131.包含头文件#include <dirent.h>2.struct dirent结构1 struct dirent2 {3 long d_ino; /* inode number 索引节点号 */4 off_t ..._struct dirnet

Simplicity Studio 4 用法_simplicity studio 4.0 uart-程序员宅基地

文章浏览阅读1.4w次,点赞2次,收藏8次。刚刚用了EFM32的Simplicity Studio 4 软件 来记录一下用法,软件可以去官网下载。第一步:首先连接好板子,打开这个软件,更新一下包,如图:后面的跟着步骤来就行,然后就等下载完成,根据网速吧,网速不好就需要等好久,趁这个时间可以泡一杯咖啡喝......第二步:配置芯片型号:点击左上角的箭头,右键选择 Device Configuration ,然后跳出一个窗口选择你所用到的芯片,..._simplicity studio 4.0 uart

yolov5 Tensorrt加速 zed取图像碰到的问题_yolov5_zed: /home/xu/tensorrt_yolov5_v6.0/src/yolo-程序员宅基地

文章浏览阅读1.4k次。原程序的功能是将samples文件夹里的照片一次性进行识别。想改变程序,用zed拍照,达到实时显示识别的目的,但是加了while(1)以及zed grab后,报错:[08/04/2020-16:01:13] [E] [TRT] …/rtSafe/safeContext.cpp (133) - Cudnn Error in configure: 7 (CUDNN_STATUS_MAPPING_ERROR)[08/04/2020-16:01:13] [E] [TRT] FAILED_EXECUTION: s_yolov5_zed: /home/xu/tensorrt_yolov5_v6.0/src/yolov5.cpp:73: nvinfer1::icuda

推荐文章

热门文章

相关标签