将namedtuple的__str__和__repr__行为带到常规类

Jer*_*meJ 2 python repr namedtuple

https://mail.python.org/pipermail/python-ideas/2014-September/029310.html

我一直认为namedtuple内置__str__并且__repr__非常整洁,我正在寻找一种简单的方法将其应用于我的任何类别.

>>> from collections import namedtuple
>>> A  = namedtuple("A", ["foo"])
>>> print(A(foo=1))
A(foo=1)
>>> str(A(foo=1))
'A(foo=1)'
>>> repr(A(foo=1))
'A(foo=1)'
Run Code Online (Sandbox Code Playgroud)

编辑:

我最初开始时是一堆冗长的,不是动态的,硬编码的__repr__.我不喜欢那样.namedtuple它是花哨的,自动的.

def __repr__(self):
    return 'className(attrA={attrA}, attrB={attrB})'.format(**vars(self)))
Run Code Online (Sandbox Code Playgroud)

Jer*_*meJ 6

有点hacky但这样做:

from collections import namedtuple

def nice_repr(obj):
    def nice_repr(self):
        return repr(
            namedtuple(
                type(self).__name__,
                vars(self)
            )(**vars(self))
        )

    obj.__repr__ = nice_repr

    return obj
Run Code Online (Sandbox Code Playgroud)

例:

@nice_repr
class A:
    def __init__(self, b, c):
        self.b = b
        self.c = c

print(repr(A(1, 2)))  # Outputs: A(c=2, b=1)
Run Code Online (Sandbox Code Playgroud)

编辑:(故障安全版)

def nice_repr(obj):
    """ Decorator to bring namedtuple's __repr__ behavior to regular classes. """

    def nice_repr(self):
        v = vars(self)

        # Prevent infinite looping if `vars` happens to include `self`.
        del(v['self'])

        return repr(namedtuple(type(self).__name__, v)(**v))

    obj.__repr__ = nice_repr

    return obj
Run Code Online (Sandbox Code Playgroud)

  • 实际上,这太过分了,对于这样一件微不足道的事情来说并不值得。在你的类中声明 `__repr__` 和 `__str__` 函数就是你所需要的 (2认同)