Skip to content Skip to sidebar Skip to footer

Get Complete List Of All Possible Class Attributes

Is there a way, given a simple Class, to output all the possible attributes for it? Standard attributes like __class__ and __doc__ and special read only attributes like __mro__, __

Solution 1:

dir() is basically a convenience method, it is not supposed to return everything, what it basically does is that it recursively returns everything found in the dictionary of a class and its bases.

PyPy's implementation of dir() is quite easy to understand:

defdir(*args):
    ...
    elifisinstance(obj, (types.TypeType, types.ClassType)):
        # Don't look at __class__, as metaclass methods would be confusing.returnsorted(_classdir(obj))
    ...

def_classdir(klass):
    """Return a set of the accessible attributes of class/type klass.

    This includes all attributes of klass and all of the base classes
    recursively.
    """
    names = set()
    ns = getattr(klass, '__dict__', None)
    if ns isnotNone:
        names.update(ns)
    bases = getattr(klass, '__bases__', None)
    if bases isnotNone:
        # Note that since we are only interested in the keys, the order# we merge classes is unimportantfor base in bases:
            names.update(_classdir(base))
    return names

As each class basically inherits from object you will see some dunder methods included because they are actually part of object's dictionary:

>>>classA(object):
    pass
...>>>set(dir(A)) == set(list(object.__dict__) + list(A.__dict__))
True

Now what about __bases__ and other missing items?

First of all object itself is an instance of something, well it's bit of a mess actually:

>>> isinstance(type, object)
True>>> isinstance(object, type)
True>>> issubclass(type, object)
True>>> issubclass(object, type)
False>>> type.mro(object)
[<type'object'>]
>>> type.mro(type)
[<type'type'>, <type'object'>]

So, all of the attributes like __bases__, __ge__ etc are actually part of type:

>>> list(type.__dict__)
['__module__', '__abstractmethods__', '__getattribute__', '__weakrefoffset__', '__dict__', '__lt__', '__init__', '__setattr__', '__subclasses__', '__new__', '__base__', '__mro__', 'mro', '__dictoffset__', '__call__', '__itemsize__', '__ne__', '__instancecheck__', '__subclasscheck__', '__gt__', '__name__', '__eq__', '__basicsize__', '__bases__', '__flags__', '__doc__', '__delattr__', '__le__', '__repr__', '__hash__', '__ge__']

Hence when we do A.__bases__ we are actually looking up a descriptor on type of A, i.e type:

>>> A.__bases__
(<type'object'>,)
>>> type(A).__dict__['__bases__'].__get__(A, type)
(<type'object'>,)

So, as A is an instance of type these methods are not part of its own dictionary but its type's dictionary.

>> classA(object):
...     spam = 'eggs'
...
>>> a = A()
>>> a.foo = 100>>> a.bar = 200>>> a.__dict__
{'foo': 100, 'bar': 200}
>>> A.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None, 'spam': 'eggs'})

As, type is a subclass of object, the dir() call on type will contain some items from object:

>>> set(dir(type)) - set(type.__dict__)
set(['__reduce_ex__', '__str__', '__format__', '__reduce__', '__class__', '__subclasshook__', '__sizeof__'])

Post a Comment for "Get Complete List Of All Possible Class Attributes"