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

Bjö*_*lex 181 python class

考虑这个课程:

class foo(object):
    pass
Run Code Online (Sandbox Code Playgroud)

默认字符串表示形式如下所示:

>>> str(foo)
"<class '__main__.foo'>"
Run Code Online (Sandbox Code Playgroud)

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

Ign*_*ams 249

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

class MC(type):
  def __repr__(self):
    return 'Wahaha!'

class C(object):
  __metaclass__ = MC

print C
Run Code Online (Sandbox Code Playgroud)

使用__str__,如果你说的是可读的字串,使用__repr__了明确的表示.

  • @Space_C0wb0y:您可以在类主体的`__repr __()`方法中将类似`_representation`的字符串添加到类主体中并返回`self self._representation`. (10认同)
  • 我想创建一些类装饰器,因此我可以轻松地为我的类设置自定义字符串表示,而无需为每个类编写元类.我不太熟悉Python的元类,所以你能给我指点吗? (2认同)
  • @ThomasLeonard:/sf/ask/2730927461/ (2认同)

小智 21

class foo(object):
    def __str__(self):
        return "representation"
    def __unicode__(self):
        return u"representation"
Run Code Online (Sandbox Code Playgroud)

  • 这会更改类的"实例"的字符串表示形式,而不是类本身. (8认同)
  • 这不能解决我的问题.试试我提供的代码. (4认同)
  • @RobertSiemer为什么?虽然他的答案没有专门针对OP的问题,但它仍然有用.它帮助了我.乍一看,我没有看到任何要求实例实施的问题.所以可能人们首先登陆这个页面. (4认同)

use*_*754 11

如果您必须在第一个之间进行选择__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)
Run Code Online (Sandbox Code Playgroud)

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

v = Vector3([1,2,3])
print repr(v)    #Vector3([1,2,3])
print str(v)     #Vector(x:1, y:2, z:3)
Run Code Online (Sandbox Code Playgroud)

  • 虽然您关于 `__repr__` 与 `__str__` 的观点是正确的,但这并没有回答实际的问题,即关于类对象,而不是实例。 (2认同)

Jon*_*ice 8

Ignacio Vazquez-Abrams 认可的答案是正确的。然而,它来自 Python 2 代。现在的 Python 3 的更新将是:

class MC(type):
  def __repr__(self):
    return 'Wahaha!'

class C(object, metaclass=MC):
    pass

print(C)
Run Code Online (Sandbox Code Playgroud)

如果您想要在 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)
Run Code Online (Sandbox Code Playgroud)

最后,如果您有一个类想要自定义静态表示,上面的基于类的方法效果很好。但是如果你有几个,你就必须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)
Run Code Online (Sandbox Code Playgroud)

印刷:

Wahaha! Booyah! Gotcha!
Run Code Online (Sandbox Code Playgroud)

元编程不是你每天都需要的东西——但是当你需要它时,它真的很到位!