Comparing two class types in python

前端 未结 4 2179
时光取名叫无心
时光取名叫无心 2021-02-20 12:07

I have two classes defined in a module classes.py:

class ClassA(object):
    pass

class ClassB(object):
    pass

And in another m

相关标签:
4条回答
  • 2021-02-20 12:38

    If you want to check if types are equal then you should use is operator.

    Example: we can create next stupid metaclass

    class StupidMetaClass(type):
        def __eq__(self, other):
            return False
    

    and then class based on it:

    • in Python 2

      class StupidClass(object):
          __metaclass__ = StupidMetaClass
      
    • in Python 3

      class StupidClass(metaclass=StupidMetaClass):
          pass
      

    then a simple check

    StupidClass == StupidClass
    

    returns False, while the next check returns an expected True value

    StupidClass is StupidClass
    

    So as we can see == operator can be overridden while there is no simple way to change is operator's behavior.

    0 讨论(0)
  • 2021-02-20 12:39

    You're comparing the type of the class object, which are all of type 'type'.

    If you just want to compare the classes, compare them directly:

    print Class3 == Class4
    
    0 讨论(0)
  • 2021-02-20 12:46

    In addition to the other answers :

    Python uses the concept of metaclasses, which are basically "classes of classes". That means, even a Class is an object in Python, which has its own class - accessible using the type in-build function.

    Because ClassA and ClassB are by default instances of the same metaclass, the comparisons return True.

    If you'd like to know more about metaclasses, this SO post is a good start.

    0 讨论(0)
  • 2021-02-20 12:58

    Explanation

    This is why your comparison doesn't work as expected

    >>> class ClassA(object):
    ...     pass
    ... 
    >>> class ClassB(object):
    ...     pass
    ... 
    >>> type(ClassB)
    <class 'type'> 
    >>> type(ClassA)
    <class 'type'> 
    >>> type(ClassA) == type(ClassB)
    True
    

    But why do ClassA and ClassB have the same type type? Quoting the docs:

    By default, classes are constructed using type(). The class body is executed in a new namespace and the class name is bound locally to the result of type(name, bases, namespace).

    Example:

    >>> ClassB
    <class '__main__.ClassB'>
    >>> type('ClassB', (), {})
    <class '__main__.ClassB'>
    >>> type(ClassB)
    <class 'type'>
    >>> type(type('ClassB', (), {}))
    <class 'type'>
    

    Getting the type of ClassB is exactly the same as getting the type of type('ClassB', (), {}), which is type.

    Solutions

    Compare them directly (w/out using the type() function):

    >>> ClassA
    <class '__main__.ClassA'>
    >>> ClassB
    <class '__main__.ClassB'>
    >>> ClassA == ClassB
    False
    

    or initialize them and compare the types of their objects:

    >>> a = ClassA()
    >>> b = ClassB()
    >>> type(a) 
    <class '__main__.ClassA'>
    >>> type(b) 
    <class '__main__.ClassB'>
    >>> type(a) == type(b)
    False
    

    FWIW you can also use is in place of == (for classes).

    0 讨论(0)
提交回复
热议问题