Python编码爬坑指南

  自己最近有在学习python,这实在是一门非常短小精悍的语言,很喜欢这种语言精悍背后又有强大函数库支撑的语言。可是刚接触不久就遇到了让人头疼的关于编码的问题,在网上查了很多资料现在在这里做一番总结,权当一个记录也为后来的兄弟姐妹们服务,如果可以让您少走一些弯路本人将倍感荣幸。

  先来描述下现象吧:

import os
for i in os.listdir("E:\Torchlight II"):
    print i

  代码很简单我们使用os的listdir函数遍历了E:\Torchlight II这个目录(Torchlight ?! :)),由于这个目录下有些文件是以中文命名的,所以在最后print结果时出现了乱码,像这样:

  那么问题出在哪儿呢? 别急,我们一点一点来分析它。

  从这里这里我们几乎能够肯定的知道问题是出在:

This means that the python console app can‘t write the given character to the console‘s encoding.
More specifically, the python console app created a _io.TextIOWrapperd instance with an encoding that cannot represent the given character.
sys.stdout --> _io.TextIOWrapperd --> (your console)

  看到这里不知你是否与我想的一样,能不能去设置console的编码,将其设置为能够理解中文字符的编码不就可以正常的显示出中文了吗?等等,让我们在多Google一会儿,

Python determines the encoding of stdout and stderr based on the value of the LC_CTYPE variable, but only if the stdout is a tty. So if I just output to the terminal, LC_CTYPE (or LC_ALL) define the encoding. However, when the output is piped to a file or to a different process, the encoding is not defined, and defaults to 7-bit ASCII.

  更详细的说明如下:

1). When Python finds its output attached to a terminal, it sets the sys.stdout.encoding attribute to the terminal‘s encoding. The print statement‘s handler will automatically encode unicode arguments into str output.
2). When Python does not detect the desired character set of the output, it sets sys.stdout.encoding to None, and print will invoke the "ascii" codec.

  嚯嚯,看来刚才的想法是可行的只是不太优雅罢了,因为我们得去修改系统的设置。事实上上面的论述是基于linux环境的,在linux下可能需要我们去更改某个环境变量的值(LC_CTYPE or LANG);如果我们是在windows下面的话,console的编码设置是跟操作系统的区域设置相关的。比如在中文的win7环境下,console默认的编码就是GBK(cp936)。你可以试试下面的代码:

import locale
print locale.getdefaultlocale()[1]

  console的编码不好设置了那能否对stdout.out.encoding进行设置以达到我们的目的呢?很遗憾,答案是否定的,这家伙压根就是只读的:

  没有办法了么?不会,其实我们离成功已经很近了,来,根据上面检索到的那些资料分析整理下看看我们现在掌握到的情况都有哪些:

  1). console不能正常显示中文,console的编码是由操作系统决定的(windows环境下);

 2). 我的操作系统是win7中文版(GBK),enc = locale.getdefaultlocale()[1];

3). console的编码决定了sys.stdout.encoding的取值,sys.stdout.encoding = utf-8;

4). 从操作系统枚举目录(E:\Torchlight II)列表返回的字符串也是GBK编码

  是不是已经看出问题来了。最上面截图中那么奇奇怪怪的问号尖角符号就是因为字符串本身是按照gbk进行编码的,但是由于sys.stdout.encoding = utf-8,导致print会按照utf-8对input的数据进行encode从而转换为unicode字符。这,当然错误了。原因已经清楚了,来改改代码吧:

import os
for i in os.listdir("E:\Torchlight II"):
    print i.decode(‘gbk‘)

  在代码中我们手动告诉了python对读入的字符串按章gbk编码来进行解码,而这一个动作之后数据已经是标准的unicode字符了,可以放心的交给print去打印输出了(即使这会儿sys.stdout.encoding = utf-8):

ps:

  实际在google中还查到过很多相关的类似编码的问题,比如这里的,还有这里的。虽然问题的样子千变万化并且解决方式多种多样甚至是python自己的特定解决方式,比如这里。但这些问题本质都是一样的都是关于字符的编码和解码,搞清楚了其中的本质所有问题都能够迎刃而解。

  给出几篇我认为有价值的参考资料:

  http://docs.python.org/howto/unicode.html#history-of-character-codes Unicode HOWTO

  http://farmdev.com/talks/unicode/ Unicode In Python, Completely Demystified

  http://www.stereoplex.com/blog/python-unicode-and-unicodedecodeerror Python, Unicode and UnicodeDecodeError

  http://www.joelonsoftware.com/articles/Unicode.html The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets

出处:http://www.cnblogs.com/pinopino/archive/2012/10/04/2711347.html

时间: 2024-10-12 19:25:59

Python编码爬坑指南的相关文章

iOS通俗易懂的微信支付接入和爬坑指南,十分钟轻松搞完

现在基本所有的App都会接入支付宝支付以及微信支付,也有很多第三方提供给你 SDK帮你接入,但是这种涉及到支付的东西还是自己服务器搞来的好一些,其实搞懂了 逻辑非常的简单,下面直接给大家说说下基本流程和接入需要注意的东西. 前期准备(这个东西一般来讲我们不需要来操心,但是还是稍微介绍下) 1.到微信开放平台注册账号点击打开链接 2.进入管理中心------移动应用------创建移动应用----根据页面完善应用资料 3.审核过后,通过应用详情页面,查看应用详情,查看AppID和AppSecret

(转)PEP 8——Python编码风格指南

PEP 8--Python编码风格指南标签(空格分隔): Python PEP8 编码规范原文:https://lizhe2004.gitbooks.io/code-style-guideline-cn/content/python/python-pep8.html https://python.freelycode.com/contribution/detail/47------PEP8中文版 -- Python编码风格指南(上,中,下) https://python.freelycode.c

【爬坑】Python 3.6 在 Socket 编程时出现类型错误 TypeError: a bytes-like object is required, not 'str'

1. 问题描述 Python 3.6 在 Socket 编程时出现错误如下 Traceback (most recent call last): File "F:/share/IdeaProjects/test/mypython/test/test10_tcpclient.py", line 17, in <module> sock.send(str) TypeError: a bytes-like object is required, not 'str' Process

Tinker + Bugly + Jenkins 爬坑之路

前阵子 Android 端的线上崩溃比较多,热修复被提上日程.实现方案是 Tinker,Jenkins 打包,最后补丁包上传到 Bugly 进行分发.主要在 Jenkins 打包这一块爬了不少坑,现记录下来,供大家参考. 1. Tinker + Bugly热修复实现 首先是本地实现,按照官方文档,只要一步一步按照文档来,这个步骤还是比较容易的,这里就不再赘述了,不懂的可以先参考官方文档:Bugly Android热更新使用指南.Bugly Android热更新详解.这里贴一下接入流程: 打基准包

Python 编码风格参考

代码除了用来运行外,更多的是用来读.为了是代码的可读性更强,很多编程语言都有自己的编码规范.规范的制定是为了保持代码的一致性,以使代码更美观和易读.代码应该怎么样排版和编写并不是绝对的,所以一些地方会有争议.有时风格指南并不适用,最重要的知道何时不一致.当你无法判断该怎么做时,应该所参考下其他的例子. 本文仅是一个 Python 编码风格的参考,并不是一个规定,规定必须要这么去做.本文的目的应该是起一个指导作用,指导开发者去写更易读的代码. 号:923414804 群里有志同道合的小伙伴, 互帮

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

Python文件头部模板 先说个小知识点:如何在创建文件的时候自动添加文件的头部信息! 通过:file--settings 每次都通过file--setings打开设置页面太麻烦了!可以通过:View--选中Toolbar工具条 修改后的效果: 一.Python Script 模板第一行 这个很简单告诉系统用什么解释去解释,如果你直接用python python_file_name.py的话这个没什么影响可以不加. 但是如果想直接通过./python_file_name.py去运行的话就得加上!

【转】Python——编码规范

来自于 啄木鸟社区 Python Coding Rule --- hoxide 初译 dreamingk 校对发布 040724 --- xyb 重新排版 040915 --- ZoomQuiet MoinMoin 美化 050610 用Python进行开发时的编码风格约定 原文:PEP 008 <Style Guide for Python Code> 下载(中文pdf): PythonCodingRule.pdf 进一步的: Google Python Style Guide Python

Python 编码的前世今生

本文导航 -ASCII -EASCII (ISO/8859-1) -GBK -Unicode -UTF-8 -Python 字符编码 -str 与 unicode 的转换 -str(s) 与 unicode(s) -乱码 -其他技巧 这是我在知乎上回答的一个问题: Python 编码为什么那么蛋疼? [1],期间收到了不少赞,不过发现我的回答还存在一些误导,于是通过查找资料重新整理了一篇,希望能解答你对编码的困惑. 一旦走上了编程之路,如果你不把编码问题搞清楚,那么它将像幽灵一般纠缠你整个职业生

python编码问题,从隐隐作痛到除去病根

查阅的资料链接 python编码为什么这么蛋疼 python2.7手册str函数 python源文件默认编码与内部默认编码 1.源文件默认编码为ASCII,所以,如果不显示声明当前代码用什么编码写的,python会用ASCII去解析,如果源文件中有UTF-8编码,由于ASCII不能翻译UTF8编码,则会报错了. #file test.py 使用UTF8保存 a='a' b='好' 运行后 SyntaxError: Non-ASCII character '\xe5' in file test.p