TransWikia.com

Python: How to write __repr__ when having __slots__

Stack Overflow Asked by sampleuser on February 6, 2021

I am wondering how to implement the __repr__ method for a class with __slots__. As far as I understand __repr__, it is supposed to return a string which can be used to construct the object of which we called __repr__. In other words, giving repr(object) to a Python interpreter should construct object.

However, if there is a class having __slots__, I find it hard to imagine how to implement this. This is because when using __slots__, some of the attributes in slots may be initialised and have values, others probably won’t. So how do I figure out which attributes were initialised and there values to pass them to the __repr__ string?

Minimal example of such a class:

class TestClass:
    __slots__ = 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', '__dict__'

    def __init__(self, something, something_else, **kwargs):
        self.something = something
        self.something_else = something_else

        for key, value in kwargs.items():
            setattr(self, key, value)

    def __repr__(self):
        return '%s(%r, %r)' %(self.__class__.__name__, self.something, self.something_else)

Any suggestions?

One Answer

As far as I understand __repr__, it is supposed to return a string which can be used to construct the object of which we called __repr__. In other words, giving repr(object) to a Python interpreter should construct object.

That's just a suggestion, not an imposition:

If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned.

And "if at all possible" is interpreted very loosely and weakly, many objects don't bother at all e.g. the repr of a class or function could yield the source representation thereof, but don't, because there's little use case for it and it'd be more annoying than useful.

However, if there is a class having __slots__, I find it hard to imagine how to implement this. This is because when using __slots__, some of the attributes in slots may be initialised and have values, others probably won't.

Certainly not. I've never written a class with slots where not all slots were filled all the time. Plus hasattr/getattr work just fine with slots.

Though I have to ask: are you cargo-culting __slots__? Did somebody once tell you to use slots and now you're using them everywhere?

slots are a memory optimisation tool, the point is for instance to need exactly one pointer per member (+ some object overhead) rather than the overhead of a dict instance (and its amortised reallocations). It makes very little sense to use slots when you're generally not filling them, and even less to add __dict__ to your slots.

Not to mention recent Python 3 iterations have added various optimisations to instance-dicts making slots even less useful, at least as the number of attributes increase (on fairly large classes as of 3.6 we found less than 5% difference, though on small classes it's likely still significant).

Answered by Masklinn on February 6, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP