Reading the docs, it seems that there's no ability to do a custom repr for a particular attribute. E.g., It would be nice to be able to specify a function for repr like:
@attr.s
class Datapoint:
image = attr.ib(type=np.ndarray, repr = lambda x: '<array of shape {} and dtype {}>'.format(x.shape, x.dtype))
label = attr.ib(type=int)
so that when you print(Datapoint(img, lab)), it does not display numpy's awkward default formatting.
As far as I see you can currently only set a boolean flag repr=False to disable to whole attribute from being shown in the object's repr, which is not what I want. We could still maintain this behaviour if we just say repr: Optional[Union[bool, Callable[[Any], str]]]=True
wow. i've been using attrs for a long time, and i was searching the issue tracker to see whether this feature was considered before... only to find that _exactly_ what i am also looking for has been posted only 10 hours before.
thanks for writing it up @peteroconnor-bc, this is exactly what i would like to have as well.
here's a preliminary pull request to explore what it could look like: #568
I have mixed feelings about this, but maybe we can sort this out. My plan is to make the whole creation of methods pluggable (I have to admit that I have been lazy or swamped – depending on how charitable you are). I.e. you pass a method-factory to @attr.s(repr=your_repr_factory) and then you do whatever the fuck you want. My first thought is to use singledispatch here too.
However that doesn't seem to preclude the need to modify the behavior of single attributes so I guess who could do both?
for class level custom repr, one can already pass repr=False and then you can implement your own __repr__ dunder method.
this means the main (only?) usefulness of custom repr callables is to have this on a per-attribute level, e.g. you don't want your np.ndarray or whatever weird object to clutter debugging output or turn your interactive python shell into a mess, while still having some useful info (unlike repr=False which will just omit it).
and as my preliminary pull request shows, this is mostly an extension of existing behaviour without any backward compatibility concerns. the repr attribute would simply change from bool to Union[bool, Callable[T]].
@wbolster nice, was not expecting someone to implement this already
I also was just reviewing some code using attrs yesterday which would have been simplified by this feature (it was also a case of handling np.ndarray fields).
for class level custom repr, one can already pass repr=False and then you can implement your own
__repr__dunder method.
Yes, but then you need to know a bunch of attrs "internals" and write some loops.
E.g., take the use case in #41 itself, where the logic at the class level now needs to be "Ask all the attrs for their own reprs, then give me those, and I know how to assemble a class-whole one".
Still think there's a chance it might be nice to have some class-level help, but yeah possibly that can decouple from this since obviously the attr-specific stuff is even more important, can always come back for the other side if it continues to be annoying (I suspect for me it likely will be personally, since I essentially always want #41 as my repr, but yeah...).
yeah let's keep class repr separate. incidentally, it was me who opened #41 ;)
closing this issue because it is pretty much identical to #212.
Most helpful comment
@wbolster nice, was not expecting someone to implement this already