0

我正在使用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)

有没有相当简单的方法来实现这一点?

4

3 回答 3

0

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

于 2018-02-08T21:34:26.517 回答
0

不,没有,这也是一个相当具体的要求。:) 人们一直在寻求更多的方法来repr通过传递例如 callable 来自定义 's 的输出,这样一旦它落地,可能会使您的用例更容易。但是,我不知道现在有任何人在积极地从事这方面的工作。

于 2017-12-06T06:31:27.767 回答
0

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

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)
于 2017-12-05T21:40:23.030 回答