Mitä eroa on __str__
ja __repr__
välillä Pythonissa?
Ellet nimenomaisesti tee toisin, useimmilla luokilla ei ole hyödyllisiä tuloksia kummankaan osalta:
>>> class Sic(object): pass
...
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>>
Kuten näet -- ei eroa, eikä muuta tietoa kuin luokan ja objektin id
. Jos ohitat vain toisen näistä kahdesta....:
>>> class Sic(object):
... def __repr__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
... def __str__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>>
kuten näet, jos ohitat __repr__
, sitä käytetään myös __str__
:lle, mutta ei päinvastoin.
Muita tärkeitä tietoja: __str__
sisäänrakennetussa kontissa käyttää __repr__
, EI __str__
, sisältämilleen kohteille. Ja huolimatta siitä, että tyypillisissä dokumenteissa on paljon sanoja aiheesta, tuskin kukaan vaivautuu tekemään objektien __repr__
:stä merkkijonon, jota eval
voi käyttää rakentaakseen samanarvoisen objektin (se on vain liian vaikeaa, JA koska ei tiedetä, miten kyseinen moduuli todella tuotiin, se on suorastaan mahdotonta).
Joten neuvoni: keskity siihen, että __str__
on kohtuullisen helppolukuinen ja __repr__
niin yksiselitteinen kuin mahdollista, vaikka se haittaisikin epätarkkaa ja saavuttamatonta tavoitetta saada __repr__
:n palautettu arvo hyväksyttäväksi syötteeksi __eval__
:lle!
__repr__
: python-olion esitys, yleensä eval muuntaa sen takaisin kyseiseksi olioksi.
__str__
: on mitä tahansa, mitä luulet objektiksi tekstimuodossa.
esim.
>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
w'o"w
^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True
Kirjasta an (An Unofficial) Python Reference Wiki (arkistokopio) by effbot:
__str__
"laskee objektin "epävirallisen" merkkijonoesityksen. Tämä eroaa __repr__
:stä siinä, että sen ei tarvitse olla kelvollinen Python-lauseke: sen sijaan voidaan käyttää kätevämpää tai tiiviimpää esitystä."