问题:如何为类对象创建自定义字符串表示形式?
考虑此类:
class foo(object):
pass
默认的字符串表示形式如下所示:
>>> str(foo)
"<class '__main__.foo'>"
如何使它显示自定义字符串?
回答 0
在类的元类中实施__str__()
或__repr__()
。
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object):
__metaclass__ = MC
print C
使用__str__
,如果你说的是可读的字串,使用__repr__
了明确的表示。
回答 1
class foo(object):
def __str__(self):
return "representation"
def __unicode__(self):
return u"representation"
回答 2
如果必须在第一个之间进行选择__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) #x:1, y:2, z:3
回答 3
伊格纳西奥·巴斯克斯(Ignacio Vazquez-Abrams)的批准答案是正确的。但是,它来自Python 2代。当前Python 3的更新为:
class MC(type):
def __repr__(self):
return 'Wahaha!'
class C(object, metaclass=MC):
pass
print(C)
如果您想要同时在Python 2和Python 3上运行的代码,则需要介绍以下六个模块:
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)
最后,如果您想拥有一个自定义静态repr的类,则上述基于类的方法效果很好。但是,如果您有几个,则必须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!
元编程不是您通常每天都需要的东西,但是,当您需要它时,它真的很实用!
回答 4
只需添加所有好的答案,我的版本就会带有修饰:
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)
标准输出:
Wahaha!
缺点:
C
没有超类就不能声明(noclass C:
)C
实例将是一些奇怪派生的实例,因此也最好__repr__
为这些实例添加一个。