Все ваши выходы в норме. Кстати, это:
reload(sys)
sys.setdefaultencoding('utf8')
на самом деле хитрость для бедного человека, чтобы установить кодировку Python по умолчанию. Это редко действительно полезно - ИМХО, это не показано в коде - и должно использоваться только тогда, когда нет более чистого способа. Я использовал Python 2 десятилетиями с кодировкой, отличной от ascii (Latin1), и использовал это только в моих самых первых скриптах.
И # -*- coding: utf-8 -*-
здесь также не используется Python, хотя это может быть полезно для вашего текстового редактора: это имеет смысл, только если у вас есть unicode буквенные строки в вашем скрипте - то, чего у вас нет .
Теперь, что на самом деле происходит:
Вы определяете row
как 2 кортежа (байтовых) строк, содержащих китайские символы, закодированные в utf8. Хорошо.
Когда вы печатаете строку, символы передаются непосредственно в систему вывода (здесь терминал или экран). Поскольку он правильно обрабатывает UTF8, он преобразует представление байта utf8 в соответствующие символы. Таким образом, print (row[0])
(который выполняется как print row[0]
в Python 2 - (row[0])
не является кортежем, (row[0],)
является 1-кортежем) правильно отображает китайские символы.
Но когда вы печатаете кортеж, Python фактически печатает представление элементов кортежа (оно будет одинаковым для списка, набора или карты). А в Python 2 представление строки байта или юникода кодирует все не ASCII-символы в \x..
из \u....
форм.
В интерактивном сеансе Python вы должны увидеть:
>>> print rows[0]
已
>>> print repr(rows[0])
'\xe5\xb7\xb2'
TL / DR: когда вы печатаете контейнеры, вы фактически печатаете представление элементов. Если вы хотите отобразить строковые значения, используйте явный цикл или объединение:
print '(' + ', '.join(rows) + ')'
отображается как положено:
(已, 经激活的区域语言)