ARTICLE AD BOX
Given some object o in Python, how do I get a list of all instance (not class) attributes which that object has?
For most objects, this is simple: just check o.__dict__, either directly or via vars(). However, this is complicated by the existence of __slots__:
If a class defines __slots__, it doesn't even have __dict__, in which case vars() and o.__dict__ won't even work
Unless, of course, it includes __dict__ in __slots__, in which case it will have them, but they'll only list attributes which do not have their own slots
A slot can be empty, so just because an attribute is listed in there doesn't mean this instance actually has that attribute
A class can inherit slots, including the __dict__ slot, from its parent classes, so I can't just iterate over type(o).__slots__ either
Technically, __slots__ doesn't have to be a list or tuple; it can be any iterable, including a non-repeatable iterator which will be consumed when the class definition is executed. E.g. class Foo: __slots__ = f"slot_{n}" for n in range(3) is perfectly legal and will create a class with 3 slots ('slot_0', 'slot_1', and 'slot_2'), but Foo.__slots__ will just return the exhausted iterator rather than a list of slots.
The built-in function dir() almost works - it lists instance attributes, both from __dict__ and from slots - but it has one minor and one major issue:
It doesn't differentiate between full and empty slots. This isn't a fatal flaw, since I could just try to get each attribute with getattr() and catch AttributeError to find empty ones, but it is an annoyance.
It returns class as well as instance members, which I very much do no want, and I don't know of any simple, reliable way to filter them out.
