Czy istnieje konwencja python, w przypadku gdy należy wdrożyć __str__()
versus __unicode__()
. Zauważyłem, że klasy zastępują __unicode__()
częściej niż __str__()
, ale nie wydają się być spójne. Czy istnieją konkretne zasady, gdy lepiej jest wdrożyć jeden w stosunku do drugiego? Czy jest to niezbędne/dobrej praktyki do wdrożenia obu?Python __str__ versus __unicode__
Odpowiedz
__str__()
to stara metoda - zwraca bajty. __unicode__()
to nowa, preferowana metoda - zwraca znaki. Nazwy są nieco mylące, ale w wersji 2.x utknęliśmy z nimi ze względu na kompatybilność. Generalnie, należy umieścić wszystkie kryteria formatowania w __unicode__()
i stworzyć zalążek __str__()
metody:
def __str__(self):
return unicode(self).encode('utf-8')
w 3,0, str
zawiera znaki, więc te same metody są nazywane __bytes__()
i __str__()
. Te zachowują się zgodnie z oczekiwaniami.
Wraz ze zmniejszaniem się świata istnieje szansa, że dowolny ciąg znaków, który napotkasz, będzie w końcu zawierał Unicode. Dlatego w przypadku nowych aplikacji należy przynajmniej podać __unicode__()
. Niezależnie od tego, czy zastąpisz także __str__()
, to tylko kwestia gustu.
Gdybym nie dbał szczególnie o mikro-optymalizację uszeregowania dla danej klasy, zawsze implementowałbym tylko __unicode__
, ponieważ jest bardziej ogólny. Kiedy zależy mi na tak drobnych problemach z wydajnością (co jest wyjątkiem, a nie regułą), mając tylko __str__
(kiedy mogę udowodnić, że nigdy nie będą to znaki spoza ASCII w wyfiszerowanym wyjściu) lub oba (jeśli oba są możliwe), może pomóc.
Sądzę, że są to solidne zasady, ale w praktyce bardzo często jest WIEDZIEĆ, że nie będzie nic poza znakami ASCII bez wysiłku, aby to udowodnić (np. Ujęta forma ma tylko cyfry, znaki interpunkcyjne i być może krótkie nazwy ASCII; -) w takim przypadku dość typowe jest przejście bezpośrednio do podejścia "just __str__
" (ale jeśli zespół programistów, z którym pracowałem zaproponował lokalną wytyczną, aby tego uniknąć, byłbym +1 w sprawie wniosku, ponieważ łatwo jest błądzić w tych sprawach ORAZ "przedwczesna optymalizacja jest źródłem wszelkiego zła w programowaniu" ;-).
W python 2.6.2, niedawno został wyzwolony, bo przypadkach konkretnej wbudowanej podklasy Exception dały inne wyniki z str (e) i unicode (e). str (e) dał przyjazne dla użytkownika wyjście; unicode (e) dawał różne, nieprzyjazne dla użytkownika wydruki. Czy jest to uważane za błędne zachowanie? Klasa to UnicodeDecodeError; Nie wymieniłem tego z góry, aby uniknąć nieporozumień - fakt, że wyjątek jest związany z Unicode, nie jest szczególnie istotny. –
Jeśli pracujesz w obu python2 i python3 w Django, polecam python_2_unicode_compatible dekorator:
Django umożliwia łatwe do zdefiniowania str() i unicode() metody, które działają na Python 2 i 3: musisz zdefiniować metodę zwracania tekstu i zastosować metodę dekoratora python_2_unicode_compatible().
Jak wspomniano we wcześniejszych komentarzach do innej odpowiedzi, niektóre wersje future.utils również obsługują tego dekoratora. W moim systemie potrzebowałem zainstalować nowszy moduł przyszłości dla Pythona2 i zainstalować przyszłe dla Pythona3. Po tym, to tutaj jest funkcjonalny przykład:
#! /usr/bin/env python
from future.utils import python_2_unicode_compatible
from sys import version_info
@python_2_unicode_compatible
class SomeClass():
def __str__(self):
return "Called __str__"
if __name__ == "__main__":
some_inst = SomeClass()
print(some_inst)
if (version_info > (3,0)):
print("Python 3 does not support unicode()")
else:
print(unicode(some_inst))
Oto przykład wyjście (gdzie venv2/venv3 są virtualenv przypadki):
~/tmp$ ./venv3/bin/python3 demo_python_2_unicode_compatible.py
Called __str__
Python 3 does not support unicode()
~/tmp$ ./venv2/bin/python2 demo_python_2_unicode_compatible.py
Called __str__
Called __str__
- 1. Znak w postaci łańcucha znaków w języku Python dla __unicode__?
- 2. Python: Przywróć bazowe zachowanie __str__
- 3. Django: Więcej pythonic __unicode__
- 4. pymssql versus pyodbc versus adodbapi versus ...
- 5. Python: __str__, ale dla klasy, a nie instancji?
- 6. Dlaczego Python rozmowę __str__ zamiast zwracania wartości długiej
- 7. Python os.stat (nazwa_pliku) .st_size versus os.path.getsize (nazwa_pliku)
- 8. metaphone versus soundex versus NYSIIS
- 9. macrodef versus script versus javascript
- 10. Różnica między __str__ a __repr__?
- 11. itertools.accumulate() versus functools.reduce()
- 12. Jaki jest cel __str__ i __repr__?
- 13. ArrayList versus array of objects versus Collection of T
- 14. . versus $ w Haskell
- 15. AbstractFactory Versus Bridge Pattern
- 16. org.codehaus.jackson versus com.fasterxml.jackson.core
- 17. apache_request_headers() versus $ _SERVER
- 18. System.Web.Http.Authorize versus System.Web.Mvc.Authorize
- 19. TaskFactory.StartNew versus ThreadPool.QueueUserWorkItem
- 20. BOOST_FOREACH versus dla pętli
- 21. MvcBuildViews Versus Razor Generator
- 22. EJS: <% = versus <% -
- 23. boost lambda versus phoenix
- 24. openssl versus windows capi
- 25. . Net Parse versus Convert
- 26. any_of Versus find_if
- 27. map versus mapM behavior
- 28. dispatch_after versus performSelector afterDelay
- 29. .Net Remoting versus WCF
- 30. Python: "TypeError: __str__ zwrócił ciąg znaków", ale nadal drukuje na wyjściu?
oznacza tworzenie metod __unicode__ i __str__ lub po prostu ciągi znaków w _ (u "") i tworzenie __string__ (bez metody unicode)? – muntu
Czy jest jakaś pułapka w realizacji tylko jednego z nich? Co stanie się, gdy zaimplementujesz tylko '__unicode__', a następnie zrobisz' str (obj) '? – RickyA
'unicode' podnosi' NameError' na Pythonie 3, jest prosty wzór, który działa zarówno w 2 i 3? –