【问题标题】:Only show non-default attributes in repr of attr.s class仅在 attr.s 类的 repr 中显示非默认属性
【发布时间】:2018-05-19 14:36:12
【问题描述】:

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

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

【问题讨论】:

    标签: python-attrs


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回复! repr 的更多定制肯定会很棒。目前,自定义类装饰器满足了我的特殊需求。
    【解决方案2】:

    我想我想出了一个办法,使用以下类装饰器:

    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)
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2020-08-16
        • 2012-02-08
        • 1970-01-01
        • 2020-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 1970-01-01
        相关资源
        最近更新 更多