Jawaban:
Alex merangkum dengan baik tetapi, yang mengejutkan, terlalu ringkas.
Pertama, izinkan saya mengulangi poin utama dalam posting Alex :
__repr__
tujuannya adalah untuk tidak ambigu__str__
tujuannya adalah agar dapat dibaca__str__
menggunakan terkandung benda__repr__
Implementasi default tidak berguna
Ini sebagian besar mengejutkan karena standar Python cenderung cukup berguna. Namun, dalam hal ini, memiliki default __repr__
yang akan bertindak seperti:
return "%s(%r)" % (self.__class__, self.__dict__)
akan terlalu berbahaya (misalnya, terlalu mudah untuk masuk ke rekursi tak terbatas jika benda saling referensi). Jadi Python keluar. Perhatikan bahwa ada satu default yang benar: jika __repr__
didefinisikan, dan __str__
tidak, objek akan berperilaku seolah-olah __str__=__repr__
.
Ini berarti, secara sederhana: hampir setiap objek yang Anda implementasikan harus memiliki fungsional __repr__
yang dapat digunakan untuk memahami objek. Penerapan __str__
adalah opsional: lakukan itu jika Anda memerlukan fungsionalitas "cetak cantik" (misalnya, digunakan oleh pembuat laporan).
Tujuannya __repr__
adalah untuk tidak ambigu
Biarkan saya keluar dan mengatakannya - saya tidak percaya pada para penentang. Saya tidak benar-benar tahu cara menggunakan debugger apa pun, dan belum pernah menggunakannya secara serius. Lebih jauh lagi, saya percaya bahwa kesalahan besar dalam debugger adalah sifat dasar mereka - kebanyakan kegagalan yang saya debug terjadi sejak lama, di galaksi yang sangat jauh. Ini berarti bahwa saya benar-benar percaya, dengan semangat keagamaan, dalam penebangan. Logging adalah sumber kehidupan dari sistem server fire-and-forget yang layak. Python membuatnya mudah untuk login: dengan mungkin beberapa pembungkus khusus proyek, yang Anda butuhkan hanyalah a
log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)
Tetapi Anda harus melakukan langkah terakhir - pastikan setiap objek yang Anda implementasikan memiliki repr yang berguna, jadi kode seperti itu bisa berfungsi. Inilah sebabnya mengapa "eval" muncul: jika Anda memiliki informasi yang cukup eval(repr(c))==c
, itu berarti Anda tahu semua yang perlu diketahui c
. Jika itu cukup mudah, setidaknya dengan cara yang kabur, lakukanlah. Jika tidak, pastikan Anda memiliki informasi yang cukup tentang hal c
itu. Saya biasanya menggunakan format seperti eval:"MyClass(this=%r,that=%r)" % (self.this,self.that)
. Itu tidak berarti bahwa Anda benar-benar dapat membangun MyClass, atau bahwa itu adalah argumen konstruktor yang tepat - tetapi itu adalah bentuk yang berguna untuk menyatakan "ini adalah semua yang perlu Anda ketahui tentang instance ini".
Catatan: Saya menggunakan di %r
atas, tidak %s
. Anda selalu ingin menggunakan repr()
[atau %r
memformat karakter, setara] di dalam __repr__
implementasi, atau Anda mengalahkan tujuan repr. Anda ingin dapat membedakan MyClass(3)
dan MyClass("3")
.
Tujuannya __str__
agar dapat dibaca
Secara khusus, ini tidak dimaksudkan untuk tidak ambigu - perhatikan itu str(3)==str("3")
. Demikian juga, jika Anda menerapkan abstraksi IP, memiliki str itu terlihat seperti 192.168.1.1 baik-baik saja. Ketika menerapkan abstraksi tanggal / waktu, str dapat berupa "2010/4/12 15:35:22", dll. Tujuannya adalah untuk mewakilinya dengan cara yang ingin dibaca oleh pengguna, bukan programmer. Memotong angka yang tidak berguna, berpura-pura menjadi kelas lain - selama itu mendukung keterbacaan, itu adalah peningkatan.
Wadah ini __str__
menggunakan terkandung benda__repr__
Ini sepertinya mengejutkan, bukan? Ini sedikit, tetapi seberapa mudah dibaca jika digunakan __str__
?
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
Tidak terlalu. Secara khusus, string dalam wadah akan merasa terlalu mudah untuk mengganggu representasi string-nya. Dalam menghadapi ambiguitas, ingatlah, Python menolak godaan untuk menebak. Jika Anda ingin perilaku di atas saat Anda mencetak daftar, cukup
print "[" + ", ".join(l) + "]"
(Anda mungkin juga bisa mencari tahu apa yang harus dilakukan tentang kamus.
Ringkasan
Terapkan __repr__
untuk kelas yang Anda laksanakan. Ini harus menjadi sifat kedua. Terapkan __str__
jika Anda pikir akan bermanfaat untuk memiliki versi string yang salah di sisi keterbacaan.
__repr__
itulah yang saya butuhkan untuk debugging. Terima kasih untuk bantuannya.
Aturan praktis saya: __repr__
untuk pengembang, __str__
untuk pelanggan.
__str__
sehingga pengembang normal memiliki objek yang dapat dibaca. Di sisi lain, __repr__
adalah untuk para pengembang SDK sendiri.
Kecuali Anda secara khusus bertindak untuk memastikan sebaliknya, sebagian besar kelas tidak memiliki hasil yang bermanfaat untuk:
>>> class Sic(object): pass
...
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>>
Seperti yang Anda lihat - tidak ada perbedaan, dan tidak ada info di luar kelas dan objek id
. Jika Anda hanya mengganti satu dari dua ...:
>>> 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>
>>>
seperti yang Anda lihat, jika Anda menimpa __repr__
, itu JUGA digunakan untuk __str__
, tetapi tidak sebaliknya.
Informasi penting lainnya yang perlu diketahui: __str__
pada wadah bawaan menggunakan__repr__
, BUKAN __str__
, untuk item yang dikandungnya. Dan, terlepas dari kata-kata pada subjek yang ditemukan dalam dokumen biasa, hampir tidak ada orang yang mengganggu membuat __repr__
objek menjadi string yang eval
dapat digunakan untuk membangun objek yang sama (itu terlalu sulit, DAN tidak tahu bagaimana modul yang relevan sebenarnya diimpor membuatnya benar-benar tidak mungkin keluar).
Jadi, saran saya: fokuslah untuk membuat yang __str__
dapat dibaca manusia, dan __repr__
sejelas mungkin, bahkan jika itu mengganggu tujuan tidak jelas yang tidak dapat dicapai untuk membuat __repr__
nilai yang dikembalikan dapat diterima sebagai masukan untuk __eval__
!
eval(repr(foo))
mengevaluasi ke objek yang sama dengan foo
. Anda benar bahwa itu tidak akan berfungsi di luar kasus pengujian saya karena saya tidak tahu bagaimana modul diimpor, tetapi ini setidaknya memastikan bahwa itu berfungsi dalam beberapa konteks yang dapat diprediksi. Saya pikir ini cara yang baik untuk mengevaluasi jika hasilnya __repr__
cukup eksplisit. Melakukan ini dalam unit test juga membantu memastikan bahwa __repr__
perubahan berikut mengikuti kelas.
eval(repr(spam)) == spam
(setidaknya dalam konteks yang tepat), atau eval(repr(spam))
memunculkan a SyntaxError
. Dengan begitu Anda menghindari kebingungan. (Dan itu hampir benar untuk builtin dan sebagian besar stdlib, kecuali untuk, misalnya, daftar rekursif, di mana a=[]; a.append(a); print(eval(repr(a)))
memberi Anda [[Ellipses]]
...) Tentu saja saya tidak melakukan itu untuk benar-benar digunakan eval(repr(spam))
, kecuali sebagai pemeriksaan kewarasan dalam unit test ... tapi saya lakukan terkadang salin dan tempel repr(spam)
ke sesi interaktif.
__str__
untuk setiap elemen, bukan __repr__
? Tampak jelas salah bagi saya, karena saya menerapkan yang dapat dibaca __str__
di objek saya dan ketika itu adalah bagian dari daftar saya melihat yang lebih buruk __repr__
sebagai gantinya.
eval(repr(x))
gagal bahkan untuk tipe bawaan: class A(str, Enum): X = 'x'
akan meningkatkan SyntaxError eval(repr(A.X))
. Sedih, tapi bisa dimengerti. BTW, eval(str(A.X))
sebenarnya berfungsi, tetapi tentu saja hanya jika class A
dalam ruang lingkup - jadi mungkin tidak terlalu berguna.
str
elemen penggunaan wadah repr
karena [1, 2, 3]
! = ["1", "2, 3"]
.
__repr__
: representasi objek python biasanya eval akan mengubahnya kembali ke objek itu
__str__
: adalah apa pun yang Anda pikirkan adalah objek itu dalam bentuk teks
misalnya
>>> 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
Singkatnya, tujuannya
__repr__
adalah untuk tidak ambigu dan__str__
dapat dibaca.
Ini adalah contoh yang bagus:
>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'
Baca dokumentasi ini untuk repr:
repr(object)
Mengembalikan string yang berisi representasi objek yang dapat dicetak. Ini adalah nilai yang sama yang dihasilkan oleh konversi (kutip terbalik). Terkadang berguna untuk dapat mengakses operasi ini sebagai fungsi biasa. Untuk banyak jenis, fungsi ini berusaha untuk mengembalikan string yang akan menghasilkan objek dengan nilai yang sama ketika diteruskan ke
eval()
, jika representasi adalah string yang terlampir dalam kurung sudut yang berisi nama jenis objek bersama dengan informasi tambahan sering termasuk nama dan alamat objek. Kelas dapat mengontrol apa fungsi ini dikembalikan untuk instance-nya dengan mendefinisikan__repr__()
metode.
Berikut ini adalah dokumentasi untuk str:
str(object='')
Mengembalikan string yang berisi representasi objek yang dapat dicetak dengan baik. Untuk string, ini mengembalikan string itu sendiri. Perbedaannya
repr(object)
adalah bahwastr(object)
tidak selalu berusaha untuk mengembalikan string yang dapat diterimaeval()
; tujuannya adalah mengembalikan string yang dapat dicetak. Jika tidak ada argumen yang diberikan, mengembalikan string kosong''
,.
Apa perbedaan antara
__str__
dan__repr__
dalam Python?
__str__
(dibaca sebagai "string dunder (double-underscore)") dan __repr__
(dibaca sebagai "dunder-repper" (untuk "representasi")) keduanya adalah metode khusus yang mengembalikan string berdasarkan keadaan objek.
__repr__
menyediakan perilaku cadangan jika __str__
tidak ada.
Jadi pertama-tama seseorang harus menulis sebuah __repr__
yang memungkinkan Anda untuk mengembalikan objek setara dari string yang dikembalikannya misalnya menggunakan eval
atau dengan mengetikkannya dalam karakter-untuk-karakter dalam shell Python.
Kapan saja nanti, seseorang dapat menulis __str__
untuk representasi string yang dapat dibaca pengguna dari instance, ketika seseorang percaya itu perlu.
__str__
Jika Anda mencetak objek, atau meneruskannya ke format
,, str.format
atau str
, kemudian jika suatu __str__
metode didefinisikan, metode itu akan dipanggil, jika tidak, __repr__
akan digunakan.
__repr__
The __repr__
metode ini disebut oleh fungsi builtin repr
dan apa yang bergema di shell python Anda ketika mengevaluasi sebuah ekspresi yang mengembalikan sebuah objek.
Karena menyediakan cadangan untuk __str__
, jika Anda hanya bisa menulis satu, mulailah dengan__repr__
Inilah bantuan bawaan pada repr
:
repr(...)
repr(object) -> string
Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.
Artinya, untuk sebagian besar objek, jika Anda mengetik apa yang dicetak oleh repr
, Anda harus dapat membuat objek yang setara. Tapi ini bukan implementasi standar.
__repr__
Objek default __repr__
adalah ( sumber C Python ) sesuatu seperti:
def __repr__(self):
return '<{0}.{1} object at {2}>'.format(
self.__module__, type(self).__name__, hex(id(self)))
Itu berarti secara default Anda akan mencetak modul dari objek, nama kelas, dan representasi heksadesimal dari lokasinya dalam memori - misalnya:
<__main__.Foo object at 0x7f80665abdd0>
Informasi ini tidak terlalu berguna, tetapi tidak ada cara untuk mendapatkan bagaimana seseorang dapat secara akurat membuat representasi kanonik dari setiap contoh yang diberikan, dan itu lebih baik daripada tidak sama sekali, setidaknya memberi tahu kita bagaimana kita dapat secara unik mengidentifikasi itu dalam memori.
__repr__
bermanfaat?Mari kita lihat betapa bergunanya itu, menggunakan shell Python dan datetime
objek. Pertama-tama kita perlu mengimpor datetime
modul:
import datetime
Jika kita memanggil datetime.now
shell, kita akan melihat semua yang kita butuhkan untuk membuat ulang objek datetime yang setara. Ini dibuat oleh datetime __repr__
:
>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
Jika kita mencetak objek datetime, kita melihat format yang dapat dibaca manusia (sebenarnya, ISO). Ini diimplementasikan oleh datetime __str__
:
>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951
Ini adalah masalah sederhana untuk membuat ulang objek yang hilang karena kami tidak menetapkannya ke variabel dengan menyalin dan menempel dari __repr__
output, dan kemudian mencetaknya, dan kami mendapatkannya dalam output yang dapat dibaca manusia sama seperti objek lainnya:
>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180
Saat Anda berkembang, Anda mungkin ingin dapat mereproduksi objek dalam kondisi yang sama, jika memungkinkan. Ini, misalnya, adalah bagaimana mendefinisikan objek datetime __repr__
( sumber Python ). Ini cukup rumit, karena semua atribut yang diperlukan untuk mereproduksi objek seperti itu:
def __repr__(self):
"""Convert to formal string, for repr()."""
L = [self._year, self._month, self._day, # These are never zero
self._hour, self._minute, self._second, self._microsecond]
if L[-1] == 0:
del L[-1]
if L[-1] == 0:
del L[-1]
s = "%s.%s(%s)" % (self.__class__.__module__,
self.__class__.__qualname__,
", ".join(map(str, L)))
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
if self._fold:
assert s[-1:] == ")"
s = s[:-1] + ", fold=1)"
return s
Jika Anda ingin objek Anda memiliki representasi yang lebih dapat dibaca manusia, Anda dapat menerapkan __str__
selanjutnya. Inilah cara mengimplementasikan objek datetime ( sumber Python ) __str__
, yang mudah dilakukan karena ia memiliki fungsi untuk menampilkannya dalam format ISO:
def __str__(self):
"Convert to string, for str()."
return self.isoformat(sep=' ')
__repr__ = __str__
?Ini adalah kritik terhadap jawaban lain di sini yang menyarankan pengaturan __repr__ = __str__
.
Pengaturan __repr__ = __str__
konyol - __repr__
adalah fallback untuk __str__
dan __repr__
, ditulis untuk penggunaan pengembang dalam debugging, harus ditulis sebelum Anda menulis a__str__
.
Anda membutuhkan __str__
hanya ketika Anda membutuhkan representasi objek teks.
Tentukan __repr__
objek yang Anda tulis sehingga Anda dan pengembang lainnya memiliki contoh yang dapat direproduksi saat menggunakannya saat Anda mengembangkan. Tentukan __str__
kapan Anda membutuhkan representasi string yang dapat dibaca manusia.
type(obj).__qualname__
?
Pada halaman 358 dari buku Python scripting untuk ilmu komputasi oleh Hans Petter Langtangen, itu jelas menyatakan bahwa
__repr__
Tujuan di representasi string lengkap objek;__str__
adalah untuk mengembalikan string yang bagus untuk mencetak.Jadi, saya lebih suka memahaminya sebagai
dari sudut pandang pengguna meskipun ini adalah kesalahpahaman yang saya buat ketika belajar python.
Contoh kecil tapi bagus juga diberikan pada halaman yang sama sebagai berikut:
In [38]: str('s')
Out[38]: 's'
In [39]: repr('s')
Out[39]: "'s'"
In [40]: eval(str('s'))
Traceback (most recent call last):
File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
eval(str('s'))
File "<string>", line 1, in <module>
NameError: name 's' is not defined
In [41]: eval(repr('s'))
Out[41]: 's'
repr
sebagai mereproduksi. Lebih baik menganggapnya sebagai mewakili.
Terlepas dari semua jawaban yang diberikan, saya ingin menambahkan beberapa poin: -
1) __repr__()
dipanggil ketika Anda cukup menulis nama objek pada konsol python interaktif dan tekan enter.
2) __str__()
dipanggil ketika Anda menggunakan objek dengan pernyataan cetak.
3) Dalam hal, jika __str__
tidak ada, maka cetak dan fungsi apa pun yang menggunakan str()
panggilan__repr__()
.
4) __str__()
wadah, ketika dipanggil akan menjalankan __repr__()
metode elemen yang terkandung.
5) str()
dipanggil ke dalam __str__()
bisa berpotensi berulang tanpa kasus dasar, dan kesalahan pada kedalaman rekursi maksimum.
6) __repr__()
dapat memanggil repr()
yang akan berusaha untuk menghindari rekursi tak terbatas secara otomatis, menggantikan objek yang sudah diwakili ...
.
Untuk membuatnya lebih sederhana:
__str__
digunakan untuk menunjukkan representasi string objek Anda agar mudah dibaca oleh orang lain.
__repr__
digunakan untuk menunjukkan representasi string dari para objek.
Katakanlah saya ingin membuat Fraction
kelas di mana representasi string dari fraksi adalah '(1/2)' dan objek (kelas Fraksi) harus direpresentasikan sebagai 'Fraksi (1,2)'
Jadi kita bisa membuat kelas Fraksi sederhana:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
Dalam semua kejujuran, eval(repr(obj))
tidak pernah digunakan. Jika Anda menemukan diri Anda menggunakannya, Anda harus berhenti, karena eval
berbahaya, dan string adalah cara yang sangat tidak efisien untuk membuat serialisasi objek Anda (gunakanpickle
sebagai gantinya).
Karena itu, saya akan merekomendasikan pengaturan __repr__ = __str__
. Alasannya adalah bahwa str(list)
panggilan repr
pada elemen (saya menganggap ini sebagai salah satu kelemahan desain terbesar dari Python yang tidak ditangani oleh Python 3). Hasil aktual repr
mungkin tidak akan terlalu membantu sebagai hasil dari print [your, objects]
.
Untuk memenuhi syarat ini, dalam pengalaman saya, kasus penggunaan paling berguna dari repr
fungsi ini adalah untuk meletakkan string di dalam string lain (menggunakan pemformatan string). Dengan cara ini, Anda tidak perlu khawatir lolos dari penawaran atau apa pun. Tetapi perhatikan bahwa tidak ada yang eval
terjadi di sini.
eval(repr(obj))
adalah tes kewarasan dan aturan praktis - jika ini menciptakan kembali objek asli dengan benar maka Anda memiliki __repr__
implementasi yang layak . Itu tidak dimaksudkan bahwa Anda benar-benar membuat cerita bersambung objek dengan cara ini.
eval
secara inheren tidak berbahaya. Apakah tidak lebih berbahaya daripada unlink
, open
atau menulis ke file. Haruskah kita berhenti menulis ke file karena mungkin serangan jahat dapat menggunakan jalur file sewenang-wenang untuk memasukkan konten ke dalamnya? Semuanya berbahaya jika digunakan secara bodoh oleh orang bodoh. Idiocy berbahaya. Efek Dunning-Kruger berbahaya. eval
hanyalah sebuah fungsi.
Dari Wiki Referensi Python (An Tidak Resmi) (salinan arsip) oleh effbot:
__str__
" Menghitung representasi string" informal "dari sebuah objek. Ini berbeda dari __repr__
yang tidak harus menjadi ekspresi Python yang valid: representasi yang lebih nyaman atau ringkas dapat digunakan sebagai gantinya. "
__repr__
sama sekali tidak diperlukan untuk mengembalikan ekspresi Python vaild.
str
- Membuat objek string baru dari objek yang diberikan.
repr
- Mengembalikan representasi string kanonik objek.
Perbedaan:
str ():
repr ():
Satu aspek yang hilang dalam jawaban lain. Memang benar bahwa secara umum polanya adalah:
__str__
: dapat dibaca manusia__repr__
: tidak ambigu, mungkin dapat dibaca melalui mesineval
Sayangnya, diferensiasi ini cacat, karena Python REPL dan juga IPython digunakan __repr__
untuk mencetak objek dalam konsol REPL (lihat pertanyaan terkait untuk Python dan IPython ). Dengan demikian, proyek yang ditargetkan untuk pekerjaan konsol interaktif (misalnya, Numpy atau Pandas) telah mulai mengabaikan aturan di atas dan sebagai __repr__
gantinya memberikan implementasi yang dapat dibaca manusia .
Dari buku Fluent Python :
Persyaratan dasar untuk objek Python adalah untuk menyediakan representasi string yang dapat digunakan sendiri, satu digunakan untuk debugging dan logging, yang lain untuk presentasi kepada pengguna akhir. Itu sebabnya
metode khusus__repr__
dan__str__
ada dalam model data.
Jawaban yang sangat baik sudah mencakup perbedaan antara __str__
dan __repr__
, yang bagi saya bermuara pada yang sebelumnya dapat dibaca bahkan oleh pengguna akhir, dan yang terakhir menjadi berguna bagi pengembang. Mengingat itu, saya menemukan bahwa implementasi standar __repr__
sering gagal mencapai tujuan ini karena dihilangkan informasi yang berguna bagi pengembang.
Untuk alasan ini, jika saya memiliki yang cukup sederhana __str__
, saya biasanya hanya mencoba untuk mendapatkan yang terbaik dari kedua dunia dengan sesuatu seperti:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
Satu hal penting yang perlu diingat adalah bahwa
__str__
penggunaan kontainer mengandung objek__repr__
.
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
Python lebih memilih ambiguitas daripada keterbacaan , __str__
panggilan dari tuple
panggilan yang berisi objek __repr__
, representasi "formal" dari suatu objek. Meskipun representasi formal lebih sulit dibaca daripada yang formal, itu tidak ambigu dan lebih kuat terhadap bug.
__repr__
ketika ( __str__
) tidak didefinisikan! Jadi kamu salah.
Pendeknya:
class Demo:
def __repr__(self):
return 'repr'
def __str__(self):
return 'str'
demo = Demo()
print(demo) # use __str__, output 'str' to stdout
s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'
import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout
from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
Ketika print()
dipanggil pada hasil decimal.Decimal(23) / decimal.Decimal("1.05")
angka mentah dicetak; output ini dalam bentuk string yang dapat dicapai dengan __str__()
. Jika kita cukup memasukkan ekspresi kita mendapatkan decimal.Decimal
output - output ini dalam bentuk representasional yang dapat dicapai dengan __repr__()
. Semua objek Python memiliki dua bentuk output. Bentuk string dirancang agar dapat dibaca oleh manusia. Bentuk representasional dirancang untuk menghasilkan keluaran yang jika diumpankan ke juru bahasa Python akan (bila mungkin) mereproduksi objek yang diwakili.
__str__
dapat dipanggil pada objek dengan memanggil str(obj)
dan harus mengembalikan string yang dapat dibaca manusia.
__repr__
dapat dipanggil pada suatu objek dengan memanggil repr(obj)
dan harus mengembalikan objek internal (bidang objek / atribut)
Contoh ini dapat membantu:
class C1:pass
class C2:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
class C3:
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
class C4:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
ci1 = C1()
ci2 = C2()
ci3 = C3()
ci4 = C4()
print(ci1) #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2) #C2 class str
print(str(ci2)) #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3) #C3 class repr
print(str(ci3)) #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4) #C4 class str
print(str(ci4)) #C4 class str
print(repr(ci4)) #C4 class repr
Memahami __str__
dan __repr__
secara intuitif dan permanen membedakan mereka sama sekali.
__str__
mengembalikan string yang menyamarkan tubuh dari objek tertentu agar dapat dibaca mata
__repr__
mengembalikan tubuh daging asli dari objek tertentu (mengembalikan dirinya sendiri) untuk mengidentifikasikan kerancuan.
Lihat dalam contoh
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
Mengenai __repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
Kita dapat melakukan operasi aritmatika pada __repr__
hasil dengan nyaman.
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
jika menerapkan operasi pada __str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Tidak menghasilkan apa-apa selain kesalahan.
Contoh lain.
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
Semoga ini membantu Anda membangun alasan konkret untuk mengeksplorasi lebih banyak jawaban.
__str__
harus mengembalikan objek string sedangkan __repr__
dapat mengembalikan ekspresi python apa pun.__str__
implementasi hilang maka __repr__
fungsi digunakan sebagai fallback. Tidak ada fallback jika __repr__
implementasi fungsi hilang.__repr__
fungsi mengembalikan representasi String objek, kita bisa mengabaikan implementasi __str__
fungsi.Sumber: https://www.journaldev.com/22460/python-str-repr-functions