Search code examples
pythoninheritanceisinstance

isinstance python return different values


I am a bit lost about how isinstance() works in Python. I have used the function before, and the behavior was quite clear, until now.

A bit of context. I have a class Classifier which has a method set_kernel that can take a string or a Kernel as the parameter. I am creating from the main function an object of the Kernel type called k. When I use isinstance(k, Kernel) the answer is True. However, if I pass k as parameter to the classifier, and then I do the same check inside the function, it returns False.

Any clue about what is going on here? I attach some code snippet to make it clearer:

class Kernel(object):
    pass

class Gaussian(Kernel):
    pass

class Classifier():
    def set_kernel(kernel, *args):
        print isinstance(kernel, Kernel) # This prints False


k = Gaussian() # This is a son of Kernel
print isinstance(k, Kernel) # This prints True

c = Classifier()
c.set_kernel(k) # This prints False, check above

Thanks!

Edit 1: I have improved the coded and cleaned all the things that are not related with the problem itself.


Solution

  • If your set_kernel function is not a staticmethod the first argument is the instance if you call this function on an instance. See for example:

    class Classifier():
        def set_kernel(kernel, *args):
            print(kernel)
            print(isinstance(kernel, int))
    
    
    >>> k = 10
    >>> print(k)
    10
    >>> print(isinstance(k, int))
    True
    
    >>> c = Classifier()
    >>> c.set_kernel(k)
    <__main__.Classifier object at 0x0000020FABD0FDA0>
    False
    

    If you however make it a staticmethod it "works":

    class Classifier():
        @staticmethod
        def set_kernel(kernel, *args):
            print(kernel)
            print(isinstance(kernel, int))
    
    >>> k = 10
    >>> print(k)
    10
    >>> print(isinstance(k, int))
    True
    
    >>> c = Classifier()
    >>> c.set_kernel(k)
    10
    True
    

    or if you don't want it to be static insert another argument for the instance, typically called "self" in the parameter list:

    class Classifier():
        def set_kernel(self, kernel, *args):
            print(kernel)
            print(isinstance(kernel, int))