免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5372 | 回复: 7

python3 unicode byte [复制链接]

论坛徽章:
0
发表于 2014-03-03 19:21 |显示全部楼层
这是python的一个老话题了,python3有很大的改变,但是其实还有一些问题。
我现在有一个问题:有一个别人写的程序,不方便改,用的是python3.

这个程序会读取一个文件,我可以得到这个文件的内容。但是我目前的处理的对象文件是gbk的文件。那个程序使用的是直接read的方法。


也就是说:我可以得到一个str对象, 这个对象是unicode.  但是这个对象是通过直接读取gbk文件 生成的。我发现直接进行decode,encode都不能正确处理这个对象。

一个方法是:
  1. bit = bytes( ( ord(c) for c  in contents ))
  2. contents = bit.decode("GB18030")
复制代码
但是这个方法的效率很差,大家有没有什么方法?

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
发表于 2014-03-03 20:26 |显示全部楼层
回复 1# fengidri
没太看懂,你现在是用2还是3?


   

论坛徽章:
0
发表于 2014-03-04 08:52 |显示全部楼层
都是python3.


这样说:
contents = open("gb18030 文件“).read()

如何正确处理这个contents 对象。不能修改上面的读取方法。

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
发表于 2014-03-04 10:23 |显示全部楼层
上面那句在Python 3不能正常执行,除非"gb18030 文件“都是ASCII,因为open默认的编码是UTF-8。如果上面那句正常运行了,这个文件就是ASCII文件,返回的contents也是合法unicode字符串,其余不外乎两种情况:
其一,在Linux/Mac OS X,locale默认UTF-8,直接处理contents就完事了,输出时才考虑其它编码。
其二,在Win,locale默认本地编码,比如GBK,当项目惯例是所有源文件为GBK,就要考虑Python源文件中的编码,设置为“# -*- coding: gbk -*-”,contents还是照常处理,输出时才转为GBK。

总之,当确实需要处理unicode时,输入时尽早转为unicode,内存中只处理unicode(str),输出时再转为其它编码。其实个人觉得LZ没有提到真正的问题,而是在误区里转,尤其是下面两句连续执行,完全没有意义,从str(unicode) - bytes - str(unicode)
bit = bytes( ( ord(c) for c  in contents ))
contents = bit.decode("GB18030")

论坛徽章:
0
发表于 2014-03-04 10:45 |显示全部楼层
谢谢ls:
      问题的关键在于我不能修改前面的代码,你说的这些我都明白,这个问题很是麻烦。 但是也是可能出现的问题,不是吗?


contents是一个使用unicode解析的, gbk字符串。当然其实这中间的内容是有问题的。但是确实就有这样一个对象在这里。

由于contents使用unicode错误的解析了gbk字符,所以再使用encode是不行的。

我提供的两行代码如你所说没有意义,但是可以不用其自身的一些方法进行处理,把contents转换成bytes,再进行解码, 这个时候是可以成功的。

其意义在于绕过了contents encode方法的一检查。

但是效率很低!

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
发表于 2014-03-04 11:26 |显示全部楼层
由于contents使用unicode错误的解析了gbk字符,所以再使用encode是不行的。

我没遇到过,能否示范下Python 3如何做到这一点?一个可工作的简单示例即可。

论坛徽章:
0
发表于 2014-05-15 11:38 |显示全部楼层
我试了一下, 在 系统local 和 shell 都是 utf-8 的情况下,读取一个 gbk编码的文本 gbk.txt

这样写 python2 和 python3 都OK:

print(open('gbk.txt', 'rb').read().decode('gbk'))

关键处在于指定读取文件时以 binary 的方式读,否则python3 会试图自动将文件内容以utf8格式decode,来得到 unicode

论坛徽章:
0
发表于 2014-05-16 16:11 |显示全部楼层
open文件的时候也可以指定encoding
  1. Help on built-in function open in module io:

  2. open(...)
  3.     open(file, mode='r', buffering=-1, encoding=None,
  4.          errors=None, newline=None, closefd=True) -> file object

  5.     Open file and return a stream.  Raise IOError upon failure.
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP