Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get List of all attributes which are not inherited

If I have a parent class and a child class, I want list of all the attributes which are defined in child class but not inherited from parent class.

Note: I know I can get the list of all the attributes from parent class and get all the attributes from child class and take intersection, but this does not work in my scenario.

like image 950
Awaish Kumar Avatar asked Jan 16 '18 11:01

Awaish Kumar


1 Answers

You can use the fact, that the address of the attribute is not the same (equal) to the one inherited. See example:

from __future__ import print_function

class A:
    def f(self):
        pass

    def g(self):
        pass


class B(A):
    def f(self):
        # overriden
        pass

    def h(self):
        pass

import inspect

a = dict(inspect.getmembers(A))
# print(a)
b = dict(inspect.getmembers(B))
# print(b)

for k, v in b.items():
    if k.startswith('__'):
        continue
    if k not in a or v != a[k]:
        print('Not inherited:', k, v)

which prints:

Not inherited: f <function B.f at 0x000002523A3E00D0>
Not inherited: h <function B.h at 0x000002523A3E0158>

If not using the inspect module, a simple dir(), may work instead.

What you need is not an intersection, but a set difference. And filter out the "magic" attributes first.

EDIT You may also want to get attributes, which are 'completely new', i.e. they were never in the base class. You don't care that the overriden stuff is also 'new'. You want to go for 'brand new'.

This requires only a small modification to the code above:

for k, v in b.items():
    if k.startswith('__'):
        continue
    if k not in a:  # HERE: no 'or v != a[k]'
        print('Added in b:', k, v)
like image 194
Tomasz Gandor Avatar answered Oct 16 '22 15:10

Tomasz Gandor