Bu sınıfı düşünün:
class foo(object):
pass
Varsayılan dize gösterimi şuna benzer:
>>> str(foo)
"<class '__main__.foo'>"
Bunu özel bir dize haline nasıl getirebilirim?
Bu sınıfı düşünün:
class foo(object):
pass
Varsayılan dize gösterimi şuna benzer:
>>> str(foo)
"<class '__main__.foo'>"
Bunu özel bir dize haline nasıl getirebilirim?
Yanıtlar:
Uygulamak __str__()
veya __repr__()
sınıfın metaclass içinde.
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object):
__metaclass__ = MC
print C
Kullanım __str__
Eğer okunabilir bir stringification, kullanımı anlamına eğer __repr__
kesin beyanlar.
_representation
sınıf gövdesine ve return self._representation
içinde __repr__()
metaclass yöntemle.
__repr__
temsili varsayılanı kullanmak istemiyorsunuz C
. _representation
Üye olmanın bir alternatifi , uygun bir metasınıf üreten bir metasınıf fabrikası oluşturmaktır __repr__
(bunu çok kullanıyorsanız güzel olabilir).
class foo(object):
def __str__(self):
return "representation"
def __unicode__(self):
return u"representation"
instances
, sınıfın dize temsilini değiştirir, sınıfın kendisi için değil.
Eğer seçim yapmanız gerekiyorsa __repr__
__str__
İlk uygulama veya bu uygulama için gitmeniz gerekiyorsa, tanımlanmadığı zaman varsayılan uygulama __str__
çağrıları __repr__
gibi.
Özel Vector3 örneği:
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)
Bu örnekte, repr
doğrudan tüketilebilen / yürütülebilen bir dize döndürürken str
hata ayıklama çıktısı olarak daha kullanışlıdır.
v = Vector3([1,2,3])
print repr(v) #Vector3([1,2,3])
print str(v) #x:1, y:2, z:3
__repr__
Vs __str__
ile ilgili görüşünüz doğru olsa da bu, örneklerle değil, sınıf nesneleriyle ilgili asıl soruya cevap vermez.
Ignacio Vazquez-Abrams'ın onayladığı cevap oldukça doğru. Ancak Python 2 neslindendir. Şu anda geçerli olan Python 3 için bir güncelleme şöyle olacaktır:
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object, metaclass=MC):
pass
print(C)
Hem Python 2 hem de Python 3'te çalışan kod istiyorsanız, altı modül sizi ele alır:
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)
Son olarak, özel bir statik repr'ye sahip olmak istediğiniz bir sınıfınız varsa, yukarıdaki sınıf tabanlı yaklaşım harika çalışır. Ancak birkaç tane varsa, MC
her birine benzer bir metasınıf oluşturmanız gerekir ve bu yorucu olabilir. Bu durumda, meta programlamayı bir adım daha ileri götürmek ve bir metasınıf fabrikası oluşturmak işleri biraz daha temiz hale getirir:
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)
baskılar:
Wahaha! Booyah! Gotcha!
Metaprogramlama genellikle her gün ihtiyaç duyduğunuz bir şey değildir - ancak ihtiyacınız olduğunda, o noktaya gelir!
Sadece tüm güzel cevaplara ekleyerek, dekorasyonlu versiyonum:
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'u:
Wahaha!
Aşağı taraflar:
C
Süper bir sınıf olmadan ilan edemezsin (hayır class C:
)C
örnekler garip bir türetmenin örnekleri olacaktır, bu yüzden __repr__
örnekler için de a eklemek iyi bir fikir olabilir .