Для некоторого объекта o в Python, как мне получить список всех атрибутов экземпляра (не класса), которые имеет этот объект?
Для большинства объектов это просто: просто проверьте o.__dict__ либо напрямую, либо через vars(). Однако это осложняется существованием __slots__:
Если класс определяет __slots__, у него даже нет есть __dict__, и в этом случае vars() и o.__dict__ даже не будут работать
Если, конечно, это не включает __dict__ in __slots__, и в этом случае они будут иметься, но они будут перечислять только те атрибуты, которые не имеют свои собственные слоты
Слот может быть пустым, поэтому то, что атрибут указан там, не означает, что этот экземпляр действительно имеет этот атрибут
Класс может наследовать slots, включая слот __dict__, из его родительских классов, поэтому я не могу просто перебирать type(o).__slots__
Технически __slots__ не обязательно должен быть списком или кортежем; это может быть любой итерируемый объект, включая неповторяемый итератор, который будет использоваться при выполнении определения класса. Например. class Foo: __slots__ = f"slot_{n}" for n in range(3) совершенно легален и создаст класс с 3 слотами ("slot_0", "slot_1" и "slot_2"), но Foo.__slots__ просто вернет исчерпанный итератор, а не список слотов.
встроенная функция dir() почти работает - она перечисляет атрибуты экземпляра, как из __dict__, так и из слотов - но у нее есть одна незначительная и одна серьезная проблема:
Она не различает полные и пустые слоты. Это не фатальный недостаток, поскольку я мог бы просто попытаться получить каждый атрибут с помощью getattr() и перехватить AttributeError, чтобы найти пустые, но это раздражает.
Он возвращает класс, а также члены экземпляра, которые мне очень не нужны, и я не знаю какого-либо простого и надежного способа их отфильтровать.
Для некоторого объекта o в Python, как мне получить список всех атрибутов экземпляра (не класса), которые имеет этот объект? Для большинства объектов это просто: просто проверьте o.__dict__ либо напрямую, либо через vars(). Однако это осложняется существованием __slots__: [list] [*]Если класс определяет __slots__, у него даже нет есть __dict__, и в этом случае vars() и o.__dict__ даже не будут работать
[*]Если, конечно, это не включает __dict__ in __slots__, и в этом случае они будут иметься, но они будут перечислять только те атрибуты, которые не имеют свои собственные слоты
[*]Слот может быть пустым, поэтому то, что атрибут указан там, не означает, что этот экземпляр действительно имеет этот атрибут
[*]Класс может наследовать slots, включая слот __dict__, из его родительских классов, поэтому я не могу просто перебирать type(o).__slots__
[*]Технически __slots__ не обязательно должен быть списком или кортежем; это может быть любой итерируемый объект, включая неповторяемый итератор, который будет использоваться при выполнении определения класса. Например. class Foo: __slots__ = f"slot_{n}" for n in range(3) совершенно легален и создаст класс с 3 слотами ("slot_0", "slot_1" и "slot_2"), но Foo.__slots__ просто вернет исчерпанный итератор, а не список слотов.
[/list] встроенная функция dir() почти работает - она перечисляет атрибуты экземпляра, как из __dict__, так и из слотов - но у нее есть одна незначительная и одна серьезная проблема: [list] [*]Она не различает полные и пустые слоты. Это не фатальный недостаток, поскольку я мог бы просто попытаться получить каждый атрибут с помощью getattr() и перехватить AttributeError, чтобы найти пустые, но это раздражает.
[*]Он возвращает класс, а также члены экземпляра, которые мне очень не нужны, и я не знаю какого-либо простого и надежного способа их отфильтровать.