List all attributes which are inherited by a class

6.1k views Asked by At

Hi I have the below from which I am trying to pull data from Outlook using code obtained on StackOverflow.

Using the first loop, I am trying to gather all attributes available to the object.

Whilst running it I notice the absence of Name which is later called in the 2nd loop, I assume this is due to inheritance. Please can you assist me in finding all attributes available to a class?

import win32com.client,sys

o = win32com.client.gencache.EnsureDispatch("Outlook.Application")
ns = o.GetNamespace("MAPI")

adrLi = ns.AddressLists.Item("Global Address List")
contacts = adrLi.AddressEntries
numEntries = adrLi.AddressEntries.Count
print(type(contacts))
nameAliasDict = {}
attrs_ = dir(contacts)
for i in range(len(attrs_)):
    print((attrs_[i]))

for j in contacts:
    print(j.Name)

    sys.exit()
4

There are 4 answers

1
Right leg On

Use the super and dir built-in functions.

super refers to the instance of the mother class.

Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class.

dir returns a list of the argument's attributes.

With an argument, attempt to return a list of valid attributes for that object.

class Foo:
    def __init__(self):
        self.v = 10

class Bar(Foo):
    def __init__(self):
        super().__init__()
        print(dir(super()))

b = Bar()

Output:

[(...), 'v']

The output list contains all the attributes that are defined in the mother class. It mostly contains attributes inherited from object (the attributes between double underscores).


If you do not extend the class whose you want to know the attributes, just use dir on an instance:

>>> dir(Foo())
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'v']
0
Tadhg McDonald-Jensen On

dir(contacts) will show you all the attribute names of contacts.

I notice the absence of Name which is later called in the 2nd loop

You use j.Name not contacts.Name so there is no reason for Name to show up from the first loop. If you want to know all the available attributes on j then do dir(j).

0
Adonis On

Given two classes, Parent and Child, if you want only the inherited attributes you could use the inspect module coupled with dir:

import inspect

class Parent():
    a = 1

    def myfunc(self):
        return 2

class Child(Parent):

    c = 4


mros = inspect.getmro(Child) #returns a tuple with the class in parameter at the first position, the rest should be the parent class(es)
child_attrs = dir(mros[0])
parent_attrs = dir(mros[1])

inherited_attr = [item for item in child_attrs if item in parent_attrs]

print(parent_attrs)
print(child_attrs)
print(inherited_attr)

And you can go like this up into the hierarchy however you wish

1
tso On

Python provides a handy little builtin called dir. I can use that on a class instance to get a list of all the attributes and methods of that class along with some inherited magic methods, such as __delattr__, __dict__, __doc__, __format__, etc. You can try this yourself by doing the following:

x = dir(myClassInstance)

but what you want is:

child.__class__.__bases__[0]().getAttributes()

__bases__ is a class attribute containing tuple of base classes for this class. so if your class has only one base class, this is the answer, but if class has more than one base class, just do same for all elements from that tuple.