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.
_representationsınıf gövdesine ve return self._representationiç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, reprdoğrudan tüketilebilen / yürütülebilen bir dize döndürürken strhata 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, MCher 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:
CSü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 .