Najlepsze metody kodowania dla funkcji repr ()?
Ostatnio miałem wiele problemów z __repr__()
, format()
, i kodowania. czy wyjście __repr__()
powinno być zakodowane czy może być ciągiem unicode? czy jest najlepsze kodowanie dla wyniku __repr__()
w Pythonie? To, co chcę wypisać, ma znaki inne niż ASCII.
Używam Pythona 2.x i chcą napisać kod, który można łatwo dostosować do Pythona 3. Program używa zatem
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function # The 'Hello' literal represents a Unicode object
Oto kilka dodatkowych problemów, które mnie trapiły i szukam rozwiązania to je rozwiązuje:
- Drukowanie na terminalu UTF-8 powinno zadziałać (mam {[5] } ustawione na
UTF-8
, ale najlepiej by było, gdyby inne przypadki też zadziałały). - Orurowanie wyjścia do pliku (zakodowanego w UTF-8) powinno zadziałać (w tym przypadku
sys.stdout.encoding
toNone
). - mój kod dla wielu
__repr__()
funkcji ma obecnie wielereturn ….encode('utf-8')
, a to jest ciężkie. Czy jest coś solidnego i lżejszego? - w niektórych przypadkach mam nawet brzydkie bestie jak
return ('<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')
, tzn. reprezentacja obiektów jest zdekodowany, umieszczony w łańcuchu formatującym, a następnie ponownie zakodowany. Chciałbym uniknąć takich zawiłych przekształceń.
Co poleciłbyś zrobić, aby napisać proste __repr__()
funkcje, które zachowują się ładnie w odniesieniu do tych pytań kodowania?
3 answers
W Python2, __repr__
(i __str__
) musi zwracać obiekt string, a nie
obiekt unicode. W Python3 sytuacja jest odwrotna, __repr__
i __str__
musi zwracać obiekty unicode, a nie Obiekty byte (née string):
class Foo(object):
def __repr__(self):
return u'\N{WHITE SMILING FACE}'
class Bar(object):
def __repr__(self):
return u'\N{WHITE SMILING FACE}'.encode('utf8')
repr(Bar())
# ☺
repr(Foo())
# UnicodeEncodeError: 'ascii' codec can't encode character u'\u263a' in position 0: ordinal not in range(128)
W Python2, tak naprawdę nie masz wyboru. Musisz wybrać kodowanie dla
Zwraca wartość __repr__
.
Przy okazji, czytałeś printfails wiki? Może nie odpowiadać bezpośrednio twoje inne pytania, ale uznałem to za pomocne w wyjaśnieniu, dlaczego pewne występują błędy.
Podczas stosowania from __future__ import unicode_literals
,
'<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')
Można po prostu zapisać jako
str('<{}>').format(repr(x))
Zakładając, że str
koduje do utf-8
w Twoim systemie.
BEZ from __future__ import unicode_literals
, wyrażenie można zapisać jako:
'<{}>'.format(repr(x))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-04 13:00:12
Myślę, że dekorator poradzi sobie z niekompatybilnością w rozsądny sposób. Oto czego używam:
from __future__ import unicode_literals, print_function
import sys
def force_encoded_string_output(func):
if sys.version_info.major < 3:
def _func(*args, **kwargs):
return func(*args, **kwargs).encode(sys.stdout.encoding or 'utf-8')
return _func
else:
return func
class MyDummyClass(object):
@force_encoded_string_output
def __repr__(self):
return 'My Dummy Class! \N{WHITE SMILING FACE}'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-13 03:09:14
Używam funkcji jak poniżej:
def stdout_encode(u, default='UTF8'):
if sys.stdout.encoding:
return u.encode(sys.stdout.encoding)
return u.encode(default)
Wtedy moje __repr__
funkcje wyglądają tak:
def __repr__(self):
return stdout_encode(u'<MyClass {0} {1}>'.format(self.abcd, self.efgh))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-17 15:59:59