JomsDev
JomsDev

Reputation: 116

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.

Upvotes: 2

Views: 225

Answers (2)

user2357112
user2357112

Reputation: 280291

You forgot the self argument:

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

That means that kernel isn't the kernel. As the first positional argument, kernel takes the role of self, so it's actually the classifier. The kernel you passed to the method ends up as the first element of args.

Upvotes: 3

MSeifert
MSeifert

Reputation: 152597

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))

Upvotes: 3

Related Questions