How can we get a definitive list of everything (or nearly everything) stored in a python object?

86 Views Asked by At

When I say "stored" I mainly mean attributes, not container elements or values returned by __getitem__.

My first thought was to bypass any overloaded __getattribute__ method (aka, dot-operator) with object.__getattribute__. I thought I would then get an objects untampered-with dictionary. However, not all objects have a __dict__ attribute, including the built-in list type; The following code...

lyst  = list()
dct = object.__getattribute__(lyst, '__dict__')

... raises an attribute error:

Traceback (most recent call last):

  File "E:/python_playpen/playpen_object_dict.py", line 25, in <module>
    dct = object.__getattribute__(sidgfisdgf, '__dict__')
AttributeError: 'list' object has no attribute '__dict__'

Process finished with exit code 1

However, list does have a dir method. The following code does not throw an error.

object.__getattribute__(lyst, '__dir__')()

object.__dir__(lyst)

Does very nearly every python object have a dir method?

dir seems to return class methods, but I want ONLY the data belonging to an object, not data belonging to a class an object is instantiated from.

Given that the following: obj = Klass() obj.foo()

is usually really:

obj = Klass()
Klass.foo(obj)

foo is data in Klass's dictionary, not objs. In order to apply foo to obj you have to pass obj as an input into Klass's foo method. Then Klass.foo modifies obj in-place, or perhaps, only reads from obj.

Klass is presumably accessed from obj in two steps:

  1. look-up the key (aka, a string) __class__ in obj's dictionary.
  2. Search for foo (or whatever the method name is) in the keys of Klass's dictionary

How do we get only obj's dictionary entries? If one of the dictionary (key, value) pairs inside obj is a reference to Klass, that is fine, I just do not want the methods or class member variables stored inside of Klass. I want data (and keys) which obj's dictionary points to directly. I would call method access "in-direct" since the look-up in obj's dictionary takes us to klass's dictionary on our way to find the target of our search (the method foo).

1

There are 1 best solutions below

0
On

This is completely evil, and doesn't give names, but ... gc.get_referents() is pretty close. From the docs:

gc.get_referents(*objs)

Return a list of objects directly referred to by any of the arguments. The referents returned are those objects visited by the arguments’ C-level tp_traverse methods (if any), and may not be all objects actually directly reachable. tp_traverse methods are supported only by objects that support garbage collection, and are only required to visit objects that may be involved in a cycle. So, for example, if an integer is directly reachable from an argument, that integer object may or may not appear in the result list.