实例讲述实现转中文及转换默认编码的方法(二)
2021-07-21
本文介绍了实现转中文的方法和默认编码。分享给大家,供大家参考,如下:
一、 爬取网页信息的时候,经常需要把“\\\\\\\”之类的东西转成中文,其实就是中文编码。可以使用以下方法进行转换:
1、
>>> s = u'\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8' >>> print s 人生苦短,py是岸
2、
>>> s = r'\u4eba\u751f\u82e6\u77ed\uff0cpy\u662f\u5cb8' >>> s = s.decode('unicode_escape') >>> print s 人生苦短,py是岸
二、另外,":'' can't in 0-5: not in (128)"的字符编码问题经常遇到编码错误。
通常可以使用以下方法:
import sys reload(sys) sys.setdefaultencoding('utf-8')
这个方法就是把默认编码改成utf-8。但是这种方法不是一次性修复的,可能会使一些代码表现得很奇怪。
关于 sys.('utf-8') 的补充:
sys.('utf-8')导致的两个大问题
简单来说,这样做会使一些代码行为变得怪异,而且这种怪异性并不容易修复,因为存在一个不可见的错误。下面我们举两个例子。
1.编码错误
import chardet def print_string(string): try: print(u"%s" % string) except UnicodeError: print u"%s" % unicode(byte_string, encoding=chardet.detect(string)['encoding']) print_string(u"þ".encode("latin-1")) import sys reload(sys) sys.setdefaultencoding('utf-8') print(key_in_dict('þ'))
输出:
$~ þ $~ þ
以上代码中,默认编码无法解码。 þ -1 编码十六进制表示 c3 be,这显然超过了 128 个字符的代码集。引发异常并进入异常处理。异常处理将基于代码检测和最可能解码的代码,输出将更加可靠。
一旦我们设置为utf-8,因为utf-8的字符范围被-1完全覆盖了,所以我们就直接使用utf-8进行解码了。 c3 be 是 utf-8 中的 þ。所以我们打印出完全不同的字符。
你可能会说我们不写这样的代码。如果我们写了它们,我们会进行更正。但是如果是这样写的第三方库呢?项目依赖的第三方库就是这么有问题。如果不依赖第三方库,那么下面这个bug就逃不掉了。
2.行为异常
假设我们想找出一个键是否存在。一般来说,可行的方法有两种。
#-*- coding: utf-8 -*- d = {1:2, '1':'2', '你好': 'hello'} def key_in_dict(key) if key in d: return True return False def key_found_in_dict(key): for _key in d: if _key == key: return True return False
我们来对比一下改变系统默认编码前后这两个函数的输出。
#-*- coding: utf-8 -*- print(key_in_dict('你好')) print(key_found_dict('你好')) print(key_in_dict(u'你好')) print(key_found_in_dict(u'你好')) print('------utf-8------') import sys reload(sys) sys.setdefaultencoding('utf-8') print(key_in_dict('你好')) print(key_found_dict('你好')) print(key_in_dict(u'你好')) print(key_found_in_dict(u'你好'))
输出:
$~ True $~ True $~ False $~ False $~ ------utf-8------ $~ True $~ True $~ False $~ True
可以看到,改变默认编码后,两个函数的输出不再一致。
dict 的 in 操作符对键进行哈希运算,并比较哈希值,以确定它们是否相等。对于集合中的字符,无论是字节字符类型还是类型,哈希值都是一样的。例如{'1':1}中的u'1'会返回True,超出代码集的字符,如上例中的“”,byte字符类型的hash和type的hash是不同的.
== 运算符进行转换,将字节字符(byte,上面的'')转换为(u'')类型,然后比较转换后的结果。在系统默认编码中,"" to的转换会产生:: to both to-them as,因为超出代码集的代码集无法转换,系统会默认不相等。当系统代码被我们手动改成utf-8后,这个禁忌就被解除了,“你好”就可以成功转换了。最终结果是in和==的行为不再一致。
问题的根源:在
为了让它的语法看起来简洁易用,做了很多事情。一个例子是字节和文本之间的混淆。
中,共有三种类型,(text),str(字节,二进制数据),它们是前两种的父类型。
其实,在语言设计领域,一个字节串(of)是否应该被当作一个字符串()一直存在争议。众所周知的Java和C#投了反对票,却站在了支持者的阵营。其实在很多情况下,我们对文本进行的正则匹配、字符替换等操作,对于字节来说都是不必要的。并且认为字节是字符,所以它们的操作集是一样的。
此外,它会在必要时尝试进行字节的自动类型转换,例如在上面的 == 或连接字节和文本时。没有(),两种不同类型之间的转换是不可能的,所以需要一个默认的编码。在它诞生的年代,它是最受欢迎的(可以这么说),所以我选择了它。但是,众所周知,在需要转换的场景(128个字符吃饱)是没用的。
经过这么多年的抱怨php unicode编码转汉字,3终于学会了怎么做人。默认编码为,表示所有需要转换的情况都可以正确转换成功。
最佳做法
说了这么多,如果你不迁移到 3,你能做什么?
有几点建议:
所有文本都应该是 type,而不是 str。如果您正在操作文本并且类型为 str,那么您正在创建一个错误。
当你需要转换时,显式转换。要将字节解码为文本,请使用 var.(),将文本编码为字节,请使用 var.()。
从外部读取数据时,默认为php unicode编码转汉字,然后变成需要的文本;同理,当文本需要向外发送时,就变成字节然后发送。
PS:这里有一些与编码转换操作相关的工具供大家参考:
在线/中文转换工具:
/在线代码转换工具:
在线汉字/代码/代码转换工具:
更多对相关内容感兴趣的读者可以查看本站专题:《编码操作技巧总结》、《图片操作技巧总结》、《数据结构与算法教程》、《编程技巧总结》、 《函数使用技巧》《总结》《字符串操作技巧总结》《入门与高级经典教程》《文件与目录操作技巧总结》
希望这篇文章对大家的程序设计有所帮助。