почему python inspect.isclass считает, что экземпляр является классом? - PullRequest
5 голосов
/ 02 ноября 2010

Учитывая следующий модуль:

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

почему foo отображается в выводе 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

Я ожидал, что inspect вернется толькоDummy, поскольку это единственное определение класса в модуле.Очевидно, что junk.foo - это класс в глазах модуля inspect.Почему это?

Ответы [ 2 ]

10 голосов
/ 02 ноября 2010

До Python v2.7 inspect.isclass наивно предполагал, что все с атрибутом __bases__ должно быть классом.

Dummy * __getattr__ делает Dummy экземпляров имеющими атрибут каждый (со значением None).

Следовательно, для inspect.isclass, foo представляется классом.

Примечание: __getattr__ должен повысить AttributeError при запросе атрибута, о котором он не знает. (Это очень отличается от возврата None.)

4 голосов
/ 02 ноября 2010

Во-первых, если все отлично ответят, Джон-Эрик, я просто хотел добавить кое-что:

, если вы делаете в ipython (какой замечательный инструмент):

%psource inspect.isclass

вы получите:

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

, что сказал Джон-Эрик.

но я думаю, что вы используете python <2.6, и эта ошибка уже исправлена, это код inspect.isclass () в python2.7: </p>

return isinstance(object, (type, types.ClassType))
...