回溯:
Traceback (most recent call last):
File "venues.py", line 22, in <module>
main()
File "venues.py", line 19, in main
print_category(category, 0)
File "venues.py", line 13, in print_category
print_category(subcategory, ident+1)
File "venues.py", line 10, in print_category
print u'%s: %s' % (category['name'].encode('utf-8'), category['id'])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
代码:
# -*- coding: utf-8 -*-
# Using https://github.com/marcelcaraciolo/foursquare
import foursquare
# Prints categories and subcategories
def print_category(category, ident):
for i in range(0,ident):
print u'\t',
print u'%s: %s' % (category['name'].encode('utf-8'), category['id'])
for subcategory in category.get('categories', []):
print_category(subcategory, ident+1)
def main():
client = foursquare.Foursquare(client_id='id',
client_secret='secret')
for category in client.venues.categories()['categories']:
print_category(category, 0)
if __name__ == '__main__':
main()
答案 0 :(得分:2)
诀窍是,将所有字符串处理完全保留在源代码中。读取输入(文件/管道/控制台)时解码为Unicode,写入输出时进行编码。如果category['name']
是Unicode,请保持这种方式(删除`.encode('utf8')。
同样根据你的评论:
然而,错误 当我尝试这样做时仍然会发生:python venues.py&gt; categories.txt,但是 当输出到终端时:python venues.py
Python通常可以确定终端编码并自动编码为该编码,这就是写入终端的原因。如果使用shell重定向输出到文件,则需要通过环境变量告诉Python所需的I / O编码,例如:
set PYTHONIOENCODING=utf8
python venues.py > categories.txt
工作示例,使用我的使用cp437
编码的美国Windows控制台。源代码保存在“没有BOM的UTF-8”中。值得指出的是源代码字节是UTF-8,但声明源编码并使用Unicode字符串允许Python正确解码源,并自动编码print
输出到终端使用其默认编码
#coding:utf8
import sys
print sys.stdout.encoding
print u'üéâäàåçêëèïîì'
这里Python使用默认的终端编码,但是在重定向时,不知道编码是什么,所以默认为ascii
:
C:\>python example.py
cp437
üéâäàåçêëèïîì
C:\>python example.py >out.txt
Traceback (most recent call last):
File "example.py", line 4, in <module>
print u'üéâäàåçêëèïîì'
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-12: ordinal not in range(128)
C:\>type out.txt
None
由于我们正在使用shell重定向,因此使用shell变量来告诉Python使用哪种编码:
C:\>set PYTHONIOENCODING=cp437
C:\>python example.py >out.txt
C:\>type out.txt
cp437
üéâäàåçêëèïîì
我们也可以强制Python使用其他编码,但在这种情况下,终端不知道如何显示UTF-8
。终端仍在使用cp437
解码文件中的字节:
C:\>set PYTHONIOENCODING=utf8
C:\>python example.py >out.txt
C:\>type out.txt
utf8
üéâäàåçêëèïîì
答案 1 :(得分:0)
我不确定,但我认为罪魁祸首是u"%s: %s"
开头的“你”字符。这假设您要打印的是字节字符串而不是unicode字符串---这是合理的(*):输出字节,适当编码。修改如下:
print '%s: %s' % (category['name'].encode('utf-8'), category['id'])
这会将unicode字符串category['name']
转换为UTF-8字节字符串,然后其余的处理完成字节字符串。
(*)从一个角度来看是合理的;另一种观点是打印unicode字符串并让环境决定它应该如何编码,但是你会受到几个你无法控制的因素的影响。这就是为什么你看到输出到终端或文件的差异。要避免所有这些问题,只需打印字节字符串。