zoukankan      html  css  js  c++  java
  • 也来谈谈python编码

    一、coding:utf-8

    让我们先来看一个示例,源码文件是utf-8格式:

    print('你好 python')
    

    当使用python2执行该程序时会收到一下报错:

    File "./hello_world.py", line 2
    SyntaxError: Non-ASCII character 'xe4' in file ./hello_world.py on line 2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
    

    错误提示的意思就是存在非ASCII字符,但是却没有encoding declared,同时给了一个连接并说明包含详细原因,这个链接是一个PEP(python enhancement proper)。
    enter image description here

    这个PEP的内容总结下来就是:
    这行代码用于声明代码文件的编码格式,这个信息可以帮助python解析器使用指定的正确编码来解释代码文件。这样就可以允许直接在代码中使用utf-8编码了。
    另外需要注意的是:声明的编码格式要和代码文件的格式一样才行,否则会报错。

    来看另外一个例子:

    # -*- coding:utf-8 -*-
    print('你好 python')
    

    将这段代码保存为ANSI格式,并执行,会得到以下报错:

    $ python ./hello_python.py
      File "./hello_python.py", line 2
    SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte
    

    所以说指定编码的时候也不能全部统一指定为utf-8,而是要根据源码文件的格式来指定,两者要一致才行。

    另外又在python的官方文档找到一个说明:
    enter image description here
    意思就是说:默认情况下,python解释器(python2)把源代码文件当做ASCII编码来处理,如果源码文件是其他格式就需要通过一个特殊的注释来说明,也就是:coding:utf-8,当然编码格式支持多中,具体看codecs的支持情况。
    这里其实也是由于python诞生的太早了,那时候Unicode都还没有诞生,因此当时作者也只能选择ASCII作为默认的编码格式。python3已经将默认编码格式改为UTF-8

    总结

    所以总结下来就是,python2中,该行代码的作用是当源代码文件不是ASCII编码时,通过该行代码告诉python解释器正确的编码格式,这样python解释器才能正常解释其中的字符。
    另外,由于python3已经修改为默认情况下,将源代码文件当做UTF-8格式来处理,同时我们写代码时现在通常都会使用UTF-8格式来存储,因此python3其实是不用再写这一行代码的,除非你的源代码文件不是UTF-8格式的。

    二、sys.setdefaultencoding('utf-8')

    先来看一个例子:

    # -*- coding:utf-8 -*-
    s = '你好'
    s.encode('gb2312')
    

    执行以上代码会收到下面的报错:

    Traceback (most recent call last):
      File "./hello_str.py", line 3, in <module>
        s.encode('gb2312')
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
    

    第一次遇到这个报错时,感觉很奇怪,明明我做的是encode操作,但是为什么报错确实decode失败呢?
    这里就是先提一下了:Python里面的编码和解码也就是unicode和str这两种形式的相互转化。编码是unicode->str,相反的,解码就是str->unicode。
    而上面定义的s是str类型的,因此当调用encode时,其实默认是先做了decode,转换为Unicode,然后再执行encode编码为指定的编码的,这里报错的原因就是当做隐式编码、解码时使用的默认格式是:ASCII,但是由于s是utf-8的编码,所以解码就失败了。
    解决办法:
    1、在文件头部添加sys.setdefaultencoding('utf-8')修改默认的编码、解码格式。

    import sys
    sys.setdefaultencoding('utf-8')
    

    2、避免由程序做隐式的编码、解码,也就是说要明确str-Unicode的转换规则,但是需要编码时要确认类型是Unicode,如果不是就手动指定正确的解码格式转换为Unicode。

    s.decode('utf-8').encode('gb2312')
    

    总结

    setdefaultencoding主要在编码、解码没有明确指明编码、解码格式的时候使用。

    三、参考资料

    1、PEP 263
    2、source-code-encoding

  • 相关阅读:
    搭建kafka集群
    fluentd 安装、配置、使用介绍
    彻底解决 es 的 unassigned shards 症状
    nginx 反向代理时丢失端口的解决方案
    kubernetes的imagePullSecrets如何生成及使用
    创建MySQL数据库账号
    Linux中查找文件
    Linux快速访问多个目录
    Django查询数据库返回字典dict数据
    linux 将压缩包复制到另外一个文件夹下面
  • 原文地址:https://www.cnblogs.com/lit10050528/p/13290825.html
Copyright © 2011-2022 走看看