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

最新文章

  1. nagios检测http
  2. spring中订阅redis键值过期消息通知
  3. POJ 1611 The Suspects(并查集,简单)
  4. oracle中substr函数的用法
  5. 你有没有试过“闭上眼”使用:京东、滴滴、QQ、支付宝?
  6. 转:如何制作一个定制的 PHP 基础 Docker 镜像(一)
  7. SQL点滴14—编辑数据
  8. C#:多进程开发,控制进程数量
  9. Leetcode_83_Remove Duplicates from Sorted List
  10. 在coding或者github建立个人站点域名绑定
  11. 4 - BFS &amp; Topological Algorithm
  12. hibernate中实体与数据库中属性对应的类型
  13. 1458 Common Subsequence
  14. layui 数据表格+分页+搜索+checkbox+缓存选中项数据
  15. Lab6: Paxos
  16. Python一键安装全部依赖包
  17. 20145321《网络对抗》Exp2 后门原理与实践
  18. How To Allow Blocked Content on Internet Explorer
  19. eFrameWork学习笔记-eOleDB
  20. Android自己定义截屏功能,相似QQ截屏

热门文章

  1. NativeXml实例训练时注意事项_1
  2. MySQL连接查询驱动表被驱动表以及性能优化
  3. Windows服务监控工具Perfmon
  4. 将反向传播讲解的深入透彻的神一样的文章(numpy实现人工神经网络)
  5. php读取富文本处理html标签问题
  6. .NET进行客户端Web开发又一利器 - Ant Design Blazor
  7. 新老单点的改造——-理解Cookie、Session、Token
  8. Spring:如何实现注解的组合
  9. 动态追踪技术之SystemTap
  10. JavaScript基础对象创建模式之沙盘模式(026)