I want to verify if argument value passed to a function is an instance of X I want to make sure that some arguments are instance of a class.
Here is my code, is there a better approach?

class Object(object):

    @property
    def _attr_classes(self):
        return {'x': str, 'y': int}

    def __init__(self, x=None, y=None):

        self.x = x
        self.y = y

    def __setattr__(self, attr_name, value):

        if attr_name in self._attr_classes:
            correct_instance = self._attr_classes[attr_name]
            if value and isinstance(value, correct_instance) is False:
                raise TypeError('Error for key argument: "{0}", value: "{1}" is not instance of "{2}"'.
                                format(attr_name, value, correct_instance))
        return super(Object, self).__setattr__(attr_name, value)
You have a subtle bug in your line if value and isinstance(value, correct_instance) is False:

First, you should not identity compare to False, just use if value and not isinstance(value, correct_instance):.

Now, what if value is a falsey value, for example consider trying to do obj = Object(); obj.y = "". This will not raise a TypeError, because "" is not a truthy value, so it will never get to the isinstance because of short-circuiting.

I'm not sure why you have it in there in the first place. Were you trying to protect against None values? If that is the case, use if value is not None. Here you want identity comparison (and not equality/truthiness).

As Peilonrayz said in the comments, this is mentioned at the end of PEP8, Python's official style-guide. It is worth a read and actually quite readable.



What is nice about your code is that it allows allowing multiple classes. isinstance takes a tuple of classes to check or a single class.
So you could use {'x': str, 'y': (int, float)} and it should still work.