Pertimbangkan kelas ini:
class foo(object):
pass
Representasi string default terlihat seperti ini:
>>> str(foo)
"<class '__main__.foo'>"
Bagaimana saya bisa menjadikan tampilan ini sebagai string khusus?
Pertimbangkan kelas ini:
class foo(object):
pass
Representasi string default terlihat seperti ini:
>>> str(foo)
"<class '__main__.foo'>"
Bagaimana saya bisa menjadikan tampilan ini sebagai string khusus?
Jawaban:
Menerapkan __str__()
atau __repr__()
dalam metaclass kelas.
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object):
__metaclass__ = MC
print C
Gunakan __str__
jika Anda bermaksud pengerasan yang dapat dibaca, gunakan __repr__
untuk representasi yang tidak ambigu.
_representation
ke tubuh kelas dan return self._representation
dalam __repr__()
metode metaclass.
__repr__
untuk mewakili C
. Alternatif untuk memiliki _representation
anggota adalah dengan membuat pabrik metaclass yang menghasilkan metaclass dengan tepat __repr__
(ini bisa menyenangkan jika Anda sering menggunakan ini).
class foo(object):
def __str__(self):
return "representation"
def __unicode__(self):
return u"representation"
instances
kelas, bukan untuk kelas itu sendiri.
Jika Anda harus memilih di antara __repr__
atau __str__
pergi untuk yang pertama, sebagai __str__
panggilan implementasi standar __repr__
ketika itu tidak ditentukan.
Contoh Vector3 Kustom:
class Vector3(object):
def __init__(self, args):
self.x = args[0]
self.y = args[1]
self.z = args[2]
def __repr__(self):
return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)
def __str__(self):
return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)
Dalam contoh ini, repr
mengembalikan lagi string yang dapat langsung dikonsumsi / dieksekusi, sedangkan str
yang lebih berguna sebagai hasil debug.
v = Vector3([1,2,3])
print repr(v) #Vector3([1,2,3])
print str(v) #x:1, y:2, z:3
__repr__
vs __str__
benar, ini tidak menjawab pertanyaan aktual, yaitu tentang objek kelas, bukan instance.
Jawaban yang disetujui Ignacio Vazquez-Abrams cukup tepat. Namun, dari generasi Python 2. Pembaruan untuk Python 3 saat ini adalah:
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object, metaclass=MC):
pass
print(C)
Jika Anda menginginkan kode yang berjalan melintasi Python 2 dan Python 3, keenam modul tersebut telah Anda bahas:
from __future__ import print_function
from six import with_metaclass
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(with_metaclass(MC)):
pass
print(C)
Akhirnya, jika Anda memiliki satu kelas yang Anda ingin memiliki repr statis kustom, pendekatan berbasis kelas di atas berfungsi dengan baik. Tetapi jika Anda memiliki beberapa, Anda harus membuat metaclass yang mirip dengan MC
masing-masing, dan itu bisa melelahkan. Dalam hal itu, mengambil metaprogramming Anda satu langkah lebih jauh dan membuat pabrik metaclass membuat segalanya sedikit lebih bersih:
from __future__ import print_function
from six import with_metaclass
def custom_class_repr(name):
"""
Factory that returns custom metaclass with a class ``__repr__`` that
returns ``name``.
"""
return type('whatever', (type,), {'__repr__': lambda self: name})
class C(with_metaclass(custom_class_repr('Wahaha!'))): pass
class D(with_metaclass(custom_class_repr('Booyah!'))): pass
class E(with_metaclass(custom_class_repr('Gotcha!'))): pass
print(C, D, E)
cetakan:
Wahaha! Booyah! Gotcha!
Metaprogramming bukanlah sesuatu yang biasanya Anda butuhkan setiap hari — tetapi ketika Anda membutuhkannya, itu benar-benar tepat sasaran!
Hanya menambahkan ke semua jawaban yang bagus, versi saya dengan dekorasi:
from __future__ import print_function
import six
def classrep(rep):
def decorate(cls):
class RepMetaclass(type):
def __repr__(self):
return rep
class Decorated(six.with_metaclass(RepMetaclass, cls)):
pass
return Decorated
return decorate
@classrep("Wahaha!")
class C(object):
pass
print(C)
stdout:
Wahaha!
Sisi bawah:
C
tanpa kelas super (tidak class C:
)C
contoh akan menjadi contoh dari beberapa derivasi aneh, jadi mungkin ide yang bagus untuk menambahkan __repr__
contoh juga.