How to create a custom string representation for a class object?
考虑这个类:
1 2 | class foo(object): pass |
默认的字符串表示形式如下所示:
1 2 | >>> str(foo) "<class '__main__.foo'>" |
如何使此显示成为自定义字符串?
在类的元类中实现
1 2 3 4 5 6 7 8 | class MC(type): def __repr__(self): return 'Wahaha!' class C(object): __metaclass__ = MC print C |
使用
1 2 3 4 5 | class foo(object): def __str__(self): return"representation" def __unicode__(self): return u"representation" |
如果您必须在
自定义vector3示例:
1 2 3 4 5 6 7 8 9 10 11 | class Vector3(object): def __init__(self, args): self.x = args[0] self.y = args[1] self.z = args[2] def __repr__(self): return"x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z) def __str__(self): return"Vector3([{0},{1},{2}])".format(self.x, self.y, self.z) |
在本例中,
1 2 3 | v = Vector3([1,2,3]) print repr(v) #Vector3([1,2,3]) print str(v) #Vector(x:1, y:2, z:3) |
伊格纳西奥·瓦兹奎兹·艾布拉姆斯的回答是完全正确的。然而,它来自于Python2代。对当前python 3的更新是:
1 2 3 4 5 6 7 8 | class MC(type): def __repr__(self): return 'Wahaha!' class C(object, metaclass=MC): pass print(C) |
如果您希望代码同时运行在python 2和python 3上,那么六个模块已经介绍了:
1 2 3 4 5 6 7 8 9 10 11 | 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的类,那么上面基于类的方法非常有效。但是如果你有几个类,你就必须为每个类生成一个类似于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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) |
印刷品:
1 | Wahaha! Booyah! Gotcha! |
元编程并不是你每天都需要的东西,但是当你需要它的时候,它真的很到位!
在所有的答案中,我的版本加上装饰:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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) |
标准输出:
1 | Wahaha! |
下边: