Python2脚本Unix运行报错Windows正常:Unicode转ASCII遇TypeError
Unicode转ASCII脚本在Unix上报错:TypeError: expected a character buffer object
我写了一段Python2脚本,用来将Unicode字符替换为对应的ASCII字符,在Windows机器上运行完全正常,但部署到Unix机器上执行时,却抛出了TypeError: expected a character buffer object错误。
脚本代码
#!/usr/bin/python2 # coding=utf-8 import sys s = open(sys.argv[1], "r") table = { 0xe4: u'a', ord(u'ö'): u'o', ord(u'ü'): u'u', ord(u'é'): u'e', ord(u'ß'): u'b', } for i in s: print ("Translated Content in file:",str(i).translate(table)); s.close()
输入文件(utf8.txt)内容
sömé täßt sömé täßt sömé täßt
预期输出
Translated Content in file: some tabt Translated Content in file: some tabt Translated Content in file: some tabt
Unix上的实际报错
Traceback (most recent call last): File "unicode.py", line 17, in <module> print ("Translated Content in file:",str(i).translate(table)); TypeError: expected a character buffer object
问题原因分析
这个错误的核心在于Python2中**str(字节串)和unicode(文本字符串)的translate方法参数要求完全不同**:
unicode.translate()可以接受字典类型的映射(键是Unicode码点,值是替换的Unicode字符),这也是你脚本中table的设计思路。- 但
str.translate()只接受一个长度为256的字符串作为转换表,不能直接用字典。
在Windows上能正常运行,大概率是巧合(比如系统默认编码和文件编码刚好匹配,导致隐式转码没触发错误),但代码本身的逻辑是有问题的——你把文件读取到的str字节串直接调用translate并传入字典,这在Python2的str对象上是不被允许的。
解决方案
我们需要确保处理的是unicode对象,而不是str字节串,具体可以通过两种方式实现:
方法1:使用codecs模块按指定编码读取文件
直接用codecs.open以UTF-8编码读取文件,这样得到的每一行都是unicode对象,无需额外转码:
#!/usr/bin/python2 # coding=utf-8 import sys import codecs # 用codecs指定UTF-8编码读取文件 with codecs.open(sys.argv[1], "r", encoding="utf-8") as s: table = { 0xe4: u'a', ord(u'ö'): u'o', ord(u'ü'): u'u', ord(u'é'): u'e', ord(u'ß'): u'b', } for i in s: # 直接对unicode对象调用translate,不需要转成str print ("Translated Content in file:", i.translate(table).strip())
方法2:手动将字节串解码为unicode
如果不想引入codecs模块,可以读取字节串后手动解码为unicode,处理完成后再按需编码:
#!/usr/bin/python2 # coding=utf-8 import sys with open(sys.argv[1], "r") as s: table = { 0xe4: u'a', ord(u'ö'): u'o', ord(u'ü'): u'u', ord(u'é'): u'e', ord(u'ß'): u'b', } for i in s: # 将读取到的字节串解码为unicode unicode_line = i.decode('utf-8') # 执行转换 translated_line = unicode_line.translate(table) # 输出时可编码回字节串(或直接print,Python2会自动处理) print ("Translated Content in file:", translated_line.strip())
额外优化说明
- 加上
.strip()可以去掉每行末尾的换行符,让输出更整洁。 - 使用
with语句管理文件句柄,无需手动调用close(),代码更安全简洁。
内容的提问来源于stack exchange,提问作者Surya Chandra
相关产品推荐
相关产品推荐

