class - python - 如何为类对象创建自定义字符串表示形式?


class foo(object):


 pass



默认的字符串表示形式类似于:


>>> str(foo)


"<class '__main__.foo'>"



如何显示为自定义字符串?

时间:

在类的元类中实现__str__()__repr__()


class MC(type):


 def __repr__(self):


 return 'Wahaha!'



class C(object):


 __metaclass__ = MC



print C



如果你是指可读的stringification,请使用__str__,使用__repr__表示明确的表示。


class foo(object):


 def __str__(self):


 return"representation"


 def __unicode__(self):


 return u"representation"



如果必须在__repr____str__之间进行选择,在默认情况下,如果没有定义,则默认实现__str__调用__repr__

自定义的Vector3例子:


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)



在这个例子中,repr再次返回可以直接使用/执行的字符串,而str作为调试输出更有用。


v = Vector3([1,2,3])


print repr(v) #Vector3([1,2,3])


print str(v) #Vector(x:1, y:2, z:3)



当前python 3的更新如下:


class MC(type):


 def __repr__(self):


 return 'Wahaha!'



class C(object, metaclass=MC):


 pass



print(C)



如果希望跨python 2和python 3运行的代码,则six模块将包含以下内容:


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)



最后,如果你有一个想要自定义静态,的类,基于上面的类的方法很有效,但是如果有几个,则必须生成类似于MC的类类似于,并且可以使用,


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)



打印:


Wahaha! Booyah! Gotcha!



元编程并不是你每天都需要的东西,但是当你需要它的时候,它真的很适合你!

我只是在所有精美的答案中加入了装饰:


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



 
!

不利方面:

  • 没有super类,不能声明C (无class C: ),
  • C实例将是一些奇怪的派生实例,因此也可以为实例添加一个__repr__

...