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.

share|improve this question
1  
Note that you can use a more trivial example (such as a str instead of a sl_kernal) to demonstrate this behavior. – Nathaniel Ford 38 mins ago
    
Your posted code has syntactical errors and wouldn't compile. Please post actually runnable code that actually demonstrates the problem when run. – user2357112 36 mins ago
    
Edited correcting the syntactic errors – JomsDev 22 mins ago
up vote 2 down vote accepted

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))
share|improve this answer

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.

share|improve this answer
    
I thought "self" was a language keyword to refers to the object but that was not related to the position in the arguments. You are right, thank you. – JomsDev 19 mins ago
    
that it's named "self" is just convention. Python always passes it as first positional argument (if it's called on an instance) no matter what it's called. – MSeifert 18 mins ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.