一、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. 获取ul下面最后一个li或ul中有多少个li

    获取ul下面最后一个li或ul中有多少个li 先获取ul的对象,再通过这个对象获取li的list用for循环取值text之类的 def set_city(self, base_info): quali ...

  2. MQ系列(1)——rabbitMQ简介

    前文我们学习了 MQ的相关知识,现在我们来学习一下实现了AMQP协议的 rabbitMQ 中间件.rabbitMQ 是使用 erlang 语言编写的中间件(erlang之父 19年4月去世的,很伟大一 ...

  3. 剑指 Offer 09. 用两个栈实现队列

    剑指 Offer 09. 用两个栈实现队列 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的 ...

  4. Oracle调用Java方法(上)如何使用LoadJava命令和如何将简单的Jar包封装成Oracle方法

    最近在工作中遇到了遇到了一个需求需要将TIPTOP中的数据导出成XML并上传到FTP主机中,但是4GL这方面的文档比较少最终决定使用Oracle调用Java的方法,在使用的过程中发现有很多的坑,大部分 ...

  5. Oracle调用Java方法(下)复杂Jar包封装成Oracle方法以及ORA-29521错误

    上一篇随笔中已经说了简单的Jar是如何封装的,但是我的需求是根据TIPTOP的查询条件产生XML文件并上传到FTP主机中,那么就要涉及到XML生成的方法和FTP上传的方法 所以在Eclipse写的时候 ...

  6. 在ASP.NET 中有哪些数据验证控件(请解释ASP.NET中以什么方式进行数据验证)?

    (1)RequiredFieldValidator:检查用户是否输入: (2)CompareValidator:检查两个表单输入项的输入信息是否存在某种指定关系,比如大.等于等: (3)RangeVa ...

  7. C# CLosedXML四句代码搞定DataTable数据导出到Excel

    最近用到DataTable导出到Excel,网上看了一下,都不怎么好使,逛了下GitHub一下完美解决了 用到的.net库CLosedXML,这个库用于读取,处理和写入Excel 2007+(.xls ...

  8. caffe的python接口学习(4)mnist实例手写数字识别

    以下主要是摘抄denny博文的内容,更多内容大家去看原作者吧 一 数据准备 准备训练集和测试集图片的列表清单; 二 导入caffe库,设定文件路径 # -*- coding: utf-8 -*- im ...

  9. win7旗舰版安装 oracle 10g 不能进入图形界面的问题

    前阵子重装了系统,把dell机器自带的win7 64位(家庭版已升级旗舰版,装ORACLE正常)换回了32位系统,前两天因为一些软件开发的问题,需要把以前做的一个系统重新架起来,数据库用的是oracl ...

  10. Spring-AliasRegistry

    使用Spring 的时候我们可以很容易的为某个bean 配置一个或多个别名 <bean id="app:dataSource" class="..."&g ...