파이썬 __str__ 대 __unicode__


213

당신이 구현해야 할 때를위한 파이썬 규칙이 있습니까 __str__()대는 __unicode__(). 클래스가 __unicode__()더 자주 재정의 되는 것을 __str__()보았지만 일관성이없는 것으로 보입니다. 하나를 구현하는 것이 더 좋을 때 구체적인 규칙이 있습니까? 두 가지를 모두 구현해야합니까?

답변:


257

__str__()이전 방법입니다-바이트를 반환합니다. __unicode__()새롭고 선호되는 방법입니다. 문자를 반환합니다. 이름은 약간 혼란 스럽지만 2.x에서는 호환성을 위해 이름이 붙어 있습니다. 일반적으로 모든 문자열 형식을에 넣고 __unicode__()스텁 __str__()메소드를 작성해야합니다 .

def __str__(self):
    return unicode(self).encode('utf-8')

3.0에서 str문자를 포함하므로 동일한 메소드의 이름이 __bytes__()__str__()입니다. 이들은 예상대로 동작합니다.


2
sa는 유니 코드str 메소드 를 모두 생성 하거나 문자열을 _ (u "")로 유지 하고 유니 코드 메소드없이 문자열을 생성하는 것을 의미 합니까?
muntu

12
그중 하나만 구현할 때 함정이 있습니까? 구현 __unicode__한 다음 수행 하면 어떻게됩니까 str(obj)?
RickyA

9
unicodeNameErrorPython 3에서 a 를 발생시킵니다 .2와 3 모두에서 작동하는 간단한 패턴입니까?
bradley.ayers

1
@ bradley.ayers는 Django를 종속성으로 사용하지 않고도 future패키지를 제공합니다 python_2_unicode_compatible.
Monkpit

1
때에 따라 다르지. python3는 유니 코드를 사용하지 않고 대신 str ;) python 2 유니 코드에 대해
Eddwin Paz

23

주어진 클래스에 대해 마이크로 최적화 문자열 화에 특별히 신경 쓰지 않는다면 항상 __unicode__일반적으로 구현해야 합니다. 그러한 작은 성능 문제 (규칙이 아닌 예외 임)에 관심이 __str__있을 때 (문자열 출력에 ASCII가 아닌 문자가 없음을 증명할 수있는 경우) 또는 둘 다 (둘 다 가능할 때) 도움.

이것들은 확실한 원리라고 생각하지만 실제로는 그것을 증명하려는 노력없이 ASCII 문자 외에는 아무것도 없다는 것을 알고 있습니다 (예 : 문자열 형식에는 숫자, 문장 부호 및 짧은 ASCII 이름 만 있습니다 .-) 직접 "정확한 __str__"접근 방식 으로 넘어가는 것이 매우 일반적인 경우입니다 (하지만 프로그래밍 팀과 협력하여 지역 가이드 라인을 제안하여이를 피하기 위해 제안에 +1 할 것입니다. "조기 최적화는 프로그래밍의 모든 악의 근원";-).


2
Python 2.6.2에서는 특정 내장 Exception 하위 클래스의 인스턴스가 str (e) 및 unicode (e)와 다른 결과를 제공했기 때문에 최근에 트립되었습니다. str (e)은 사용자에게 친숙한 결과를 주었다; 유니 코드 (e)는 다른 사용자 친화적 인 출력을 제공했습니다. 이것이 버그가있는 행동으로 간주됩니까? 클래스는 UnicodeDecodeError입니다. 혼란을 피하기 위해 이름을 미리 밝히지 않았습니다. 예외가 유니 코드 관련이라는 사실은 특별히 관련이 없습니다.
Paul Du Bois 2016 년

13

세계가 점점 작아짐에 따라 발생하는 모든 문자열에 결국 유니 코드가 포함될 가능성이 있습니다. 따라서 새로운 앱의 경우 최소한을 제공해야합니다 __unicode__(). 당신이 또한 재정의 여부 __str__()는 맛의 문제입니다.


8

Django의 python2와 python3 모두에서 작업하는 경우 python_2_unicode_compatible 데코레이터를 권장합니다.

Django는 Python 2 및 3에서 작동 하는 str () 및 unicode () 메서드 를 정의하는 간단한 방법을 제공합니다. 텍스트를 반환 하는 str () 메서드를 정의 하고 python_2_unicode_compatible () 데코레이터를 적용해야합니다.

다른 답변에 대한 이전 의견에서 언급했듯이 future.utils의 일부 버전도이 데코레이터를 지원합니다. 내 시스템에서 python2를위한 최신 모듈을 설치하고 python3을위한 future를 설치해야했습니다. 그 후 다음은 기능적인 예입니다.

#! /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))

다음은 출력 예입니다 (venv2 / venv3은 virtualenv 인스턴스).

~/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__

3

Python 2 : __str __ () 만 구현하고 유니 코드를 반환합니다.

경우 __unicode__()생략되고, 누군가 전화 unicode(o)또는 u"%s"%o파이썬 통화 o.__str__()및 변환 시스템 인코딩을 사용하여 유니. (의 설명서를__unicode__() 참조하십시오 .)

그 반대입니다. 당신이 구현하는 경우 __unicode__()는 아니지만 __str__(), 다음 때 누군가가 전화 str(o)또는 "%s"%o파이썬 돌아갑니다 repr(o).


이론적 해석

unicode에서 를 반환하는 이유는 무엇 __str__()입니까?
경우 __str__()반환 유니 코드는 파이썬이 자동으로 변환 str시스템 인코딩을 사용하여.

장점은 무엇입니까?
① 시스템 인코딩이 무엇인지 걱정할 필요가 없습니다 (예 :) locale.getpreferredencoeding(…). 개인적으로는 지저분 할뿐만 아니라 어쨌든 시스템이 처리해야 할 문제라고 생각합니다. ② 조심하면 코드가 __str__()유니 코드 를 반환 하는 Python 3과 상호 호환 될 수 있습니다 .

라는 함수에서 유니 코드를 반환하는 것이 현혹 __str__()적이 지 않습니까?
조금. 그러나 이미 수행 중일 수 있습니다. from __future__ import unicode_literals파일 맨 위에 있으면 유니 코드를 모르더라도 유니 코드를 반환 할 가능성이 높습니다.

파이썬 3은 어떻습니까?
파이썬 3는 사용하지 않습니다 __unicode__(). 그러나 __str__()파이썬 2 또는 파이썬 3에서 유니 코드를 반환하도록 구현 하면 코드의 해당 부분이 호환됩니다.

unicode(o)실질적으로 다른 사람이되고 싶다면 어떻게해야 str()합니까? ( ) 및을
모두 구현하십시오 . 나는 이것이 드물다고 생각하지만, 실제로 다른 출력 (예 : for 와 같은 특수 문자의 ASCII 버전)을 원할 수도 있습니다 .__str__()str__unicode__()":)"u"☺"

나는 일부 사람들이이 논쟁을 발견 할 수 있다는 것을 알고 있습니다.


1

__unicode__파이썬 2.x에서 함수를 둘러싼 기본 동작 중 일부에 익숙하지 않은 사람들을 지적 할 가치가 __str__있습니다.

class A :
    def __init__(self) :
        self.x = 123
        self.y = 23.3

    #def __str__(self) :
    #    return "STR      {}      {}".format( self.x , self.y)
    def __unicode__(self) :
        return u"UNICODE  {}      {}".format( self.x , self.y)

a1 = A()
a2 = A()

print( "__repr__ checks")
print( a1 )
print( a2 )

print( "\n__str__ vs __unicode__ checks")
print( str( a1 ))
print( unicode(a1))
print( "{}".format( a1 ))
print( u"{}".format( a1 ))

다음과 같은 콘솔 출력을 생성합니다 ...

__repr__ checks
<__main__.A instance at 0x103f063f8>
<__main__.A instance at 0x103f06440>

__str__ vs __unicode__ checks
<__main__.A instance at 0x103f063f8>
UNICODE 123      23.3
<__main__.A instance at 0x103f063f8>
UNICODE 123      23.3

이제 __str__방법을 주석 해제하면

__repr__ checks
STR      123      23.3
STR      123      23.3

__str__ vs __unicode__ checks
STR      123      23.3
UNICODE  123      23.3
STR      123      23.3
UNICODE  123      23.3
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.