Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does python inspect.isclass think an instance is a class?

Given the following module:

class Dummy(dict):
    def __init__(self, data):
        for key, value in data.iteritems():
            self.__setattr__(key, value)

    def __getattr__(self, attr):
        return self.get(attr, None)
    __setattr__=dict.__setitem__
    __delattr__=dict.__delitem__


foo=Dummy({"one":1, "two":2})

why does foo show up in the output of inspect.getmembers(..., predicate=inspect.isclass)?

$ python2.5
Python 2.5.2 (r252:60911, Aug 28 2008, 13:13:37) 
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import junk
>>> import inspect
>>> inspect.getmembers(junk, predicate=inspect.isclass)
[('Dummy', <class 'junk.Dummy'>), ('foo', {'two': 2, 'one': 1})]
>>> inspect.isclass(junk.foo)
True

I expected that inspect would only return Dummy since that is the only class definition in the module. Apparently, though, junk.foo is a class in the eyes of the inspect module. Why is that?

like image 341
Bryan Oakley Avatar asked Nov 02 '10 20:11

Bryan Oakley


People also ask

Is instance of a class Python?

Instance is an object that belongs to a class. For instance, list is a class in Python. When we create a list, we have an instance of the list class.

How do you tell if an object is a class Python?

Using isinstance() function, we can test whether an object/variable is an instance of the specified type or class such as int or list. In the case of inheritance, we can checks if the specified class is the parent class of an object. For example, isinstance(x, int) to check if x is an instance of a class int .

How do you inspect a class in Python?

isclass(): The isclass() method returns True if that object is a class or false otherwise. When it is combined with the getmembers() functions it shows the class and its type. It is used to inspect live classes.


2 Answers

Prior to Python v2.7, inspect.isclass naively assumed anything with a __bases__ attribute must be a class.

Dummy's __getattr__ makes Dummy instances appear to have every attribute (with a value of None).

Therefore, to inspect.isclass, foo appears to be a class.

Note: __getattr__ should raiseAttributeError when asked for an attribute it does not know about. (This is very different than returning None.)

like image 85
Jon-Eric Avatar answered Oct 06 '22 12:10

Jon-Eric


First if all great answer Jon-Eric i just wanted to add some stuff:

if you do in ipython (what a great tool):

%psource inspect.isclass

you will get:

return isinstance(object, types.ClassType) or hasattr(object, '__bases__')

which what Jon-Eric said.

but i guess that you use python < 2.6 and this bug was already fixed, this is the code of inspect.isclass() in python2.7:

return isinstance(object, (type, types.ClassType))
like image 36
mouad Avatar answered Oct 06 '22 12:10

mouad