仅在 attr.s class 的 repr 中显示非默认属性

Only show non-default attributes in repr of attr.s class

我正在使用 attrs 定义没有样板代码的简单 类。装饰器自动生成一个 __repr__ 来显示所有属性的值。我只想显示没有默认值的属性:

>>> import attr
>>> @attr.s
... class Coordinates(object):
...     x = attr.ib(default=0)
...     y = attr.ib(default=0)
>>> Coordinates()  # wanted output: Coordinates()
Coordinates(x=0, y=0)
>>> Coordinates(x=0, y=0)  # wanted output: Coordinates()
Coordinates(x=0, y=0)
>>> Coordinates(x=1)  # wanted output: Coordinates(x=1)
Coordinates(x=1, y=0)
>>> Coordinates(x=1, y=1)  # output OK
Coordinates(x=1, y=1)

是否有任何相当简单的方法来实现这一目标?

我想我找到了一个方法,使用以下 class 装饰器:

def no_default_vals_in_repr(cls):
    """Class decorator on top of attr.s that omits attributes from srepr that
    have their default value"""

    defaults = OrderedDict()
    for attribute in cls.__attrs_attrs__:
        defaults[attribute.name] = attribute.default

    def repr_(self):
        real_cls = self.__class__
        qualname = getattr(real_cls, "__qualname__", None)
        if qualname is not None:
            class_name = qualname.rsplit(">.", 1)[-1]
        else:
            class_name = real_cls.__name__
        attributes = defaults.keys()
        return "{0}({1})".format(
            class_name,
            ", ".join(
                name + "=" + repr(getattr(self, name))
                for name in attributes
                if getattr(self, name) != defaults[name]))

    cls.__repr__ = repr_
    return cls

这会导致以下正确行为:

>>> @no_default_vals_in_repr
... @attr.s
... class Coordinates(object):
...     x = attr.ib(default=0)
...     y = attr.ib(default=0)
>>> Coordinates()
Coordinates()
>>> Coordinates(x=0, y=0)
Coordinates()
>>> Coordinates(x=1)
Coordinates(x=1)
>>> Coordinates(x=1, y=1)
Coordinates(x=1, y=1)

不,没有,这也是一个相当具体的要求。 :) 人们一直在寻求更多方法来自定义 repr 的输出,例如通过传递可调用,这样一来,您的用例就会更容易。但是,我不知道现在有人在积极致力于此。

您肯定需要为该场景提供自己的 __repr__。不要忘记在 class 装饰器中设置 repr=False(希望将来不需要,请参阅 https://github.com/python-attrs/attrs/issues/324)。