一、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)。

这个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的官方文档找到一个说明:



意思就是说:默认情况下,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

也来谈谈python编码的更多相关文章

  1. (转载) 浅谈python编码处理

    最近业务中需要用 Python 写一些脚本.尽管脚本的交互只是命令行 + 日志输出,但是为了让界面友好些,我还是决定用中文输出日志信息. 很快,我就遇到了异常: UnicodeEncodeError: ...

  2. Python 编码简单说

    先说说什么是编码. 编码(encoding)就是把一个字符映射到计算机底层使用的二进制码.编码方案(encoding scheme)规定了字符串是如何编码的. python编码,其实就是对python ...

  3. Python之路3【知识点】白话Python编码和文件操作

    Python文件头部模板 先说个小知识点:如何在创建文件的时候自动添加文件的头部信息! 通过:file--settings 每次都通过file--setings打开设置页面太麻烦了!可以通过:View ...

  4. python编码规范

    python编码规范 文件及目录规范 文件保存为 utf-8 格式. 程序首行必须为编码声明:# -*- coding:utf-8 -*- 文件名全部小写. 代码风格 空格 设置用空格符替换TAB符. ...

  5. 【转】python编码的问题

    摘要: 为了在源代码中支持非ASCII字符,必须在源文件的第一行或者第二行显示地指定编码格式: # coding=utf-8 或者是: #!/usr/bin/python # -*- coding: ...

  6. 转载:谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词

    转载: 谈谈Unicode编码,简要解释UCS.UTF.BMP.BOM等名词 这是一篇程序员写给程序员的趣味读物.所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级 ...

  7. 【转】python编码规范

    http://blog.csdn.net/willhuo/article/details/49300441 决定开始Python之路了,利用业余时间,争取更深入学习Python.编程语言不是艺术,而是 ...

  8. python 编码 UnicodeDecodeError

    将一个py脚本从Centos转到win运行,出错如下: UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 0: il ...

  9. Python编码/文件读取/多线程

    Python编码/文件读取/多线程 个人笔记~~记录才有成长   编码/文件读取/多线程 编码 常用的一般是gbk.utf-8,而在python中字符串一般是用Unicode来操作,这样才能按照单个字 ...

随机推荐

  1. Communication【floyd判环+并查集】

    Communication 题目链接(点击) 题目描述 The Ministry of Communication has an extremely wonderful message system, ...

  2. python常用模块-os

    得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 函数用来删除一个文件:os.remove() 删除多个目录 ...

  3. NASH:基于丰富网络态射和爬山算法的神经网络架构搜索 | ICLR 2018

    论文提出NASH方法来进行神经网络结构搜索,核心思想与之前的EAS方法类似,使用网络态射来生成一系列效果一致且继承权重的复杂子网,本文的网络态射更丰富,而且仅需要简单的爬山算法辅助就可以完成搜索,耗时 ...

  4. sql片段提取引用

    sql片段 sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下: <!-- 传递pojo综合查询用户信息 --> <select id= ...

  5. linear-gradient,radial-gradient 渐变

    一.渐变效果 ->  线性渐变 方法: background-image: linear-gradient(direction, color-stop1, color-stop2, ...); ...

  6. Mysq数据库索引(B-Tree索引)

    一.B-Tree索引的底层结构 所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,如图所示,B-Tree索引的底层数据结构一般是B+树,反应了MyISAM索引是如何工作的.     二.B-T ...

  7. S7-1200视频教程: S7-1200的功能与特点-跟我做 - 2/112

    S7-1200视频教程: S7-1200的功能与特点-跟我做 - 2/112 观看连接: http://www.elearning.siemens.com.cn/video/Course/201105 ...

  8. web安全中的session攻击

    运行着个简单的demo后,打开login.jsp,使用firebug或chrome会发现,即使没有登录,我们也会有一个JSESSIONID,这是由服务器端在会话开始是通过set-cookie来设置的匿 ...

  9. RabbitMQ:三、进阶

    保证消息的安全 持久化 交换器持久化:声明交换器时指定持久化 队列持久化:声明队列时指定持久化 消息持久化:发送消息时指定持久化 一般队列和消息持久化要同时声明,此外消息假如进了交换器却找不到队列,也 ...

  10. 重学 Java 设计模式:实战中介者模式「按照Mybaits原理手写ORM框架,给JDBC方式操作数据库增加中介者场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同龄人的差距是从什么时候拉开的 同样的幼儿园.同样的小学.一样 ...