设为首页 收藏本站
查看: 586|回复: 0

[经验分享] python 种字符编码的问题

[复制链接]

尚未签到

发表于 2017-4-30 08:57:13 | 显示全部楼层 |阅读模式
  Python中 u'吴'和'吴'有什么区别?
2009-04-27 00:20
这是我在水木问的一个问题
【 在 wuyeguo (风中飘絮) 的大作中提到: 】
: 被Python的字符编码给搞糊涂了
: 下面是我做的一些测试
: >>> len("吴".decode("utf8").encode("gb18030"))
: 2
: >>> len("吴".decode("utf8").encode("utf8"))
: 3
: >>> len("吴".decode("utf8"))
: 1
: 上面的长度,是什么导致的呢?
: >>> a = u"吴"
: >>> b = "吴".decode("utf8")
: >>> id(a)
: 3085915248L
: >>> id(b)
: 3085916040L
: 这里为什么a和b的id不一样呢?
: >>> a
: u'\u5434'
: >>> b
: u'\u5434'
: >>> a == b
: True
: >>> e="a"
: >>> f="a"
: >>> id(e)
: 3086135712L
: >>> id(f)
: 3086135712L
: >>> g=u"吴"
: >>> id(g)
: 3085916136L
: >>> h=u"吴"
: >>> id(h)
: 3085916208L
: >>> hash(g)
: 1807260213
: >>> hash(h)
: 1807260213
: >>> hash(e)
: -468864544
: >>> hash(f)
: -468864544
: 环境
: Python 2.5.1 (r251:54863, Sep 17 2007, 02:13:54)
: [GCC 4.1.1 20070105 (Red Hat 4.1.1-52)] on linux2
: 谢谢
下面是水木的xxxss同学的精彩回答
>>> print repr(u"吴".encode("gb18030"))
'\xce\xe2'

这说明你看到的是汉字或者乱码,而python看到的是一个上面这两个字节的字符串对象。
对于python2.5而言,字符类型就两种,str和unicode。
而不是100多种,上面这个是什么类型?

>>> type('\xce\xe2')
<type 'str'>
>>> type('\xce')
<type 'str'>

这说明啥?这个字符串显然是str不是unicode.那长度呢
>>> len('\xce')
1
>>> len('\xe2')
1
>>> len('\xce\xe2')
2

这是很显然的,对不对,对python而言,他并不知道你这两个字节的东西是个汉字,
他也不知道你这个东西是个什么编码格式的,它只知道这是两个字符长度的str。
同样的:

>>> print repr(u"吴".encode("utf8"))
'\xe5\x90\xb4'
>>> print type(u"吴".encode("utf8"))
<type 'str'>

这说明utf8编码后的这个字符串是3个字符长度的str,对不对?
python并不会给你100多种编码的字符每个给你一个类型,比如utf8的叫utf8str,
gb18030的叫gb18030str,不会,他们都是一种类型:str,所以,上面两种编码的字符,
对于python而言,只是'\xce\xe2'和'\xe5\x90\xb4'的区别。

>>> print repr(u"吴")
u'\u5434'

看到了吧,这次是这样一个字符
>>> print type(u"吴")
<type 'unicode'>

这说明这是个unicode类型了,并且,这个unicode类型的对象的长度是1
现在明白了吧,对你来讲,字符之间的差别是编码方式,对python来讲,差别是类型。
它只是给你提供了一些转换编码的方法,但不同的只有两种类型。


第二个问题:
>>> help(id)
Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it's the object's memory address.)

人家说的很明白了,返回的是object的内存地址,同时存在的对象之间是独立的。
你用u"吴"的时候,和你用"吴".decode("utf8")的时候的"吴",对于python而言,
理论上时独立的,因为这是两次执行过程,并没有什么相关性,完全可以理解为
这是两个object,只是这两个str的值一样罢了,python并不保证两个值一样的object
就放在同一个内存地址内。
当然了,对于某些类型的对象,比如小int和简单ascii str,python为了优化,
会使用同样的内存地址存同样的值,但这并不保证。所以尽量不要去考虑这个。
你大可以认为,同一个生产线出来的轮子,长的再一样,它也是两个轮子,放在不同的
位置,占用不同的空间。
所以:
>>> id(u"吴")
11577488
>>> id(u"吴")
11577776
>>> id("吴")
13245696
>>> id("吴")
13650880
>>> id("吴")
13304864
>>> id("吴")
13245696

至于"=="的判断,这个并不是根据"=="的统一定义来的,而是根据每个不同的类型对于
__eq__ 这样的method的实现来的。所以并不一定说id一样就True,或者值一样就True
比如str类型,python对"__eq__"的定义是内容(也就是值)相同就返回True
所以才会有:
>>> a = '吴'
>>> b = '吴'
>>> a
'\xce\xe2'
>>> b
'\xce\xe2'
>>> id(a)
13745216
>>> id(b)
13743232
>>> id(a) == id(b)
False
>>> a == b
True

而对于基类object而言,"__eq__"就很简单了,id不同就不同
>>> x = object()
>>> y = object()
>>> x == y
False
>>> x
<object object at 0x00B20468>
>>> y
<object object at 0x00B20470>



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-371041-1-1.html 上篇帖子: python学习笔记3.1.3x 下篇帖子: python 动态递归修改文件权限
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表