转自:[http://swj.me/]

介绍

一直不太喜欢使用命令行,所以去年年底的技术创新中,使用TkInter来开发小工具。结果花费了大量的时间来学习TkInter ui的使用。

最近想整理该工具,使用命令行的形式,然后将该工具做成exe的形式进行分发。在工作一开始就遇到了编码的问题。

在脚本中有如下代码,用来接收用户交互式输入的ip。

server = raw_input("请输GIS Server IP:")

在脚本文件的第一行,我已经加了如下代码

# -*-coding: utf-8 -*-

但是在windows 的控制台执行的时候,出现了乱码。有点不解,因为自己一直以来在python中,处理中文都是在文件头加入该代码。

通过搜索发现,是因为在windows cmd 默认的使用的cp936的编码。既然知道使用这种编码则将编码改为如下:

# -*-coding: cp936-*-

但是得到如下的错误:

SyntaxError: encoding problem: cp936 with BOM

百思不得其解。作为懒癌患者,就想绕过去。则采用如下方式,对单独字符串进行编码。

userName=raw_input("请输入站点管理员用户名:".decode("utf-8").encode("cp936"))

这样重要在cmd中可以正常的输出中文了。但是问题来了,我的脚本中,有上百行代码有中文。每个地方都这么写,感觉偷懒不成,反被*。

这个时候,通过搜索。逐步的发现了问题的原因。这是因为python有几个层次的编码。分别是:

  • 字符串变量级别编码
  • 脚本级别的编码
  • py文件级别的编码
  • 显示窗口的编码

字符串变量的编码

对单个字符串转码,可以使用:encode()编码成可以显示的。通常对字符串不能由一个编码直接转换为另一个编码。通常需要解码到Unicode,然后对unicode字符串重新的编码。比如上面的示例。

脚本的编码

上面通过设置 #coding:utf-8设置的就是脚本里面内容的编码。也就是该脚本文件中所有的字符串变量都采用该处设置的编码方式。

py文件的编码

py文件的编码,默认的是ANSI。但是也可以使用utf-8,unicode编码。

显示窗口的编码

上面的几种情况,中文在运行阶段不会出错。但是这些中文还不一定能够正常的显示。能否正常的显示,还有显示窗口支持的编码决定。比如cmd中中文支持GBK和cp936,所以代码中的字符串需要编码到这两种才可以显示。

测试

  1. 当py文件的编码为utf-8的时候。代码中唔需要添加#coding:utf-8 。脚本中的中文,在运行过程不会报错。
  2. 当py文件的编码为ANSI的时候。如代码中没有显示的添加 ** --coding:utf-8 -- **,则当代码中出现中文的时候,运行脚本的时候。会出现如下错误
SyntaxError: Non-ASCII character '\xe4' in file
  1. 当py文件设置为utf-8,而显示设置代码编码为#coding:936。则会出现ncoding problem: cp936 with BOM的错。这个时候,将py文件的编码改为ANSI即可。

结论

通过上面的测试,有几个结论:

  1. 编码有层次结构。文件编码影响脚本内容编码,脚本内容编码决定 其中的字符串编码。
  2. 当字符串显示设置了编码的时候。字符串的编码为显示设置的编码,此时文件和脚本编码不起作用。当字符串没有显示设置编码的时候,则采用上一级编码决定。
  3. 所以设置这三种编码的时候,需要确保三种编码之间能够转换。否则会出现上面列举的错误。

python 中几个层次的中文编码.md的更多相关文章

  1. [转]Python中的str与unicode处理方法

    早上被python的编码搞得抓耳挠腮,在搜资料的时候感觉这篇博文很不错,所以收藏在此. python2.x中处理中文,是一件头疼的事情.网上写这方面的文章,测次不齐,而且都会有点错误,所以在这里打算自 ...

  2. python2.7高级编程 笔记二(Python中的描述符)

    Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...

  3. Python中的字符串与字符编码

    本节内容: 前言 相关概念 Python中的默认编码 Python2与Python3中对字符串的支持 字符编码转换 一.前言 Python中的字符编码是个老生常谈的话题,同行们都写过很多这方面的文章. ...

  4. python中的not具体使用及意思

    python中的not具体使用及意思 name='' while not name: name=raw_input(u'请输入姓名:') print name python中的not具体表示是什么: ...

  5. python中的编码问题:以ascii和unicode为主线

      1.unicode.gbk.gb2312.utf-8的关系 http://www.pythonclub.org/python-basic/encode-detail 这篇文章写的比较好,utf-8 ...

  6. Python中reactor,factory,protocol

    最为简单的情况下,除了了解清reactor的简单使用,你还要了解Protocol和Factory.它们最终都会由reactor的侦听建立和run来统一调度起来. 建立服务器的第一个要解决的问题就是服务 ...

  7. 关于python中赋值、浅拷贝、深拷贝之间区别的深入分析

    当重新学习了计算机基础课程<数据结构和算法分析>后再来看这篇自己以前写的博文,发现错误百出.python内置数据类型之所以会有这些特性,归根结底是它采用的是传递内存地址的方式,而不是传递真 ...

  8. [转]Python中urllib与urllib2的区别与联系

    引用文章1:http://my.oschina.net/u/558071/blog/144792 引用文章2:http://zhuoqiang.me/python-urllib2-usage.html ...

  9. 8.python中的数字

    python中数字对象的创建如下, a = 123 b = 1.23 c = 1+1j 可以直接输入数字,然后赋值给变量. 同样也可是使用类的方式: a = int(123) b = float(1. ...

随机推荐

  1. Nginx设置expires设定页面缓存时间 不缓存或一直使用缓存

    配置expires expires起到控制页面缓存的作用,合理的配置expires可以减少很多服务器的请求 要配置expires,可以在http段中或者server段中或者location段中加入 l ...

  2. ipmitool sdr type Temperature sdr 从传感器获取某一类数据

    1.1.1 常用监控命令总结.ipmitool sdr type Temperature 硬件监控 yum install  OpenIPMI ipmitool ipmitool sdr type T ...

  3. sed 指定行之间的内容替换

    [root@Cobbler logs]# cat aa.txt qqq123ppp123====123[root@Cobbler logs]# sed -i '2,5s#123#456#' aa.tx ...

  4. keep learning

    fueling people’s creativity  助长了人们的创造力,燃烧了人们的激情

  5. svn & git 问题汇总

    svn: warning: W150002: '/Users/piercalex/svn/azzz/1' is already under version control svn: E200009: ...

  6. MyBatis常用对象SqlSessionFactory和SqlSession介绍和运用

    学习框架一个比较好的路径阅读源码.本文介绍的SqlSessionFactory和SqlSession.可以通过了解SqlSessionFactory接口和SqlSession接口以及两个的实现类入手, ...

  7. MyBatis学习4---使用MyBatis_Generator生成Dto、Dao、Mapping

    由于MyBatis属于一种半自动的ORM框架,所以主要的工作将是书写Mapping映射文件,但是由于手写映射文件很容易出错,所以查资料发现有现成的工具可以自动生成底层模型类.Dao接口类甚至Mappi ...

  8. C++ string类学习总结

    C++字符串技术 string类  string对象在大多数应用中被用来消除对char*指针的使用,支持所期望的一些操作; 可以转换成char*,保持和现代代码的兼容性,还能自动处理内存管理; 一些s ...

  9. C++之异常处理

     C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...

  10. 编程之美 set 5 寻找数组中最大值和最小值

    解法 1. 设置 min, max 两个变量, 然后遍历一遍数组, 比较次数为 2*N 2. 依然设置 min, max 两个变量并遍历数组, 但将遍历的 step 设置为 2, 比较次数为 1.5 ...