Home > Back-end >  Is there a way to check if two classes are identical in python?
Is there a way to check if two classes are identical in python?

Time:09-28

I want to check if two classes (not instances of these classes) are identical in the sense that they have identical class attributes.

The trivial approach is to override __eq__ and __hash__1, but this will only allow comparing instances of the classes.

I wonder if this is even possible as it seems like python uses id to check for equality between the classes which can not be overridden.

The desired outcome is something like this:

    class FOO:
        SOME_ATTR=3
    class BAR1:
        SOME_ATTR=3
    class BAR2:
        SOME_ATTR=1
set(FOO, BAR1, BAR2) == SET(FOO, BAR2)

CodePudding user response:

To get a set of attributes of a Python class, for example

class MyClass:
   my_attr: 2

you can use

set(x for x in MyClass.__dict__.keys() if not x.startswith('__'))

then compare the sets of the classes

CodePudding user response:

If you want to know if the attributes of classes are the same, you can use the inspect.getmembers() function and filter for attributes without dunders. Note that attributes of classes are mutable!

import inspect

class FOO:
    SOME_ATTR=3

    def my_func():
        pass

class BAR1:
    SOME_ATTR=3

class BAR2:
    SOME_ATTR=1



def compare_classes(class1: type, class2: type) -> bool:
    attr_class1 = inspect.getmembers(class1, lambda a:not(inspect.isroutine(a)))
    attr_class2 = inspect.getmembers(class2, lambda a:not(inspect.isroutine(a)))
    set_class1 = set([a for a in attr_class1 if not(a[0].startswith('__') and a[0].endswith('__'))])
    set_class2 = set([a for a in attr_class2 if not(a[0].startswith('__') and a[0].endswith('__'))])
    return set_class1 == set_class2


print(compare_classes(FOO, BAR1))
print(compare_classes(BAR1, BAR2))

Outcome:

True
False
  • Related