Python не имеет много ограничений семантического типа для данных функций и методов, но имеет несколько , и вот один из них: __str__
(в Python 2. *) должен возвращать байтовую строку. Как обычно, если объект unicode обнаружен там, где требуется байтовая строка, текущая кодировка по умолчанию (обычно 'ascii'
) применяется в попытке создать требуемую строку байтов из рассматриваемого объекта Unicode.
Для этой операции кодировка (если таковая имеется) любого заданного файлового объекта не имеет значения, потому что то, что возвращается из __str__
, может быть напечатано или подвергнется совершенно другой и не связанной обработке. Ваша цель в вызове __str__
не имеет значения для самого вызова и его результатов; Python, как правило, не учитывает «будущий контекст» операции (что вы собираетесь делать с результатом после выполнения операции) при определении семантики операции.
Это потому, что Python не всегда знает ваши будущие намерения и пытается минимизировать количество неожиданностей. В частности, print str(x)
и s = str(x); print s
(одни и те же операции, выполняемые одним глотком против двух) должны иметь одинаковые эффекты; если во втором случае, будет исключение, если str(x)
не сможет корректно создать строку байтов (то есть, например, x.__str__()
не может), и, следовательно, исключение должно также произойти в другом случае.
print
сам (начиная с версии 2.4, я полагаю) при представлении с объектом Unicode учитывает атрибут .encoding
(если есть) целевого потока (по умолчанию sys.stdout
); другие операции, которые еще не связаны с каким-либо конкретным целевым потоком, этого не делают, и str(x)
(т. е. x.__str__()
) является именно такой операцией.
Надеюсь, это помогло показать причину поведения, которое вас раздражает ...
Редактировать : теперь ОП поясняет: «Моя главная проблема - сделать класс« пригодным для печати », то есть print A () печатает что-то полностью читаемое (не с символами \ x *** unicode). ». Вот подход, который, я думаю, лучше всего подходит для этой конкретной цели:
import sys
DEFAULT_ENCODING = 'UTF-8' # or whatever you like best
class sic(object):
def __unicode__(self): # the "real thing"
return u'Pel\xe9'
def __str__(self): # tries to "look nice"
return unicode(self).encode(sys.stdout.encoding or DEFAULT_ENCODING,
'replace')
def __repr__(self): # must be unambiguous
return repr(unicode(self))
То есть, этот подход фокусируется на __unicode__
в качестве основного способа для экземпляров класса отформатировать себя - но поскольку (в Python 2) print
вызывает __str__
, вместо этого у него есть один делегат __unicode__
с лучшим, что он может сделать с точки зрения кодирования. Не идеально, но тогда утверждение Python 2 print
далеко не идеально; -).
__repr__
, со своей стороны, должен стремиться к быть однозначным , то есть не , чтобы «хорошо выглядеть» за счет риска двусмысленности (в идеале, когда это возможно, он должен возвращать байтовую строку, которая, если она будет передана в eval
, сделает экземпляр равным текущему ... это далеко не всегда возможно, но отсутствие неоднозначности является абсолютным ядром различие между __str__
и __repr__
, и я настоятельно рекомендую соблюдать это различие!).