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.
_representationke tubuh kelas dan return self._representationdalam __repr__()metode metaclass.
__repr__untuk mewakili C. Alternatif untuk memiliki _representationanggota 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"
instanceskelas, 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, reprmengembalikan lagi string yang dapat langsung dikonsumsi / dieksekusi, sedangkan stryang 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 MCmasing-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:
Ctanpa kelas super (tidak class C:)Ccontoh akan menjadi contoh dari beberapa derivasi aneh, jadi mungkin ide yang bagus untuk menambahkan __repr__contoh juga.