为什么python inspect.isclass认为实例是一个类?

时间:2010-11-02 20:30:11

标签: python introspection

给出以下模块:

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是检查模块眼中的一个类。那是为什么?

2 个答案:

答案 0 :(得分:10)

在Python v2.7之前,inspect.isclass天真地认为具有__bases__属性的任何内容都必须是一个类。

Dummy的{​​{1}}个__getattr__个实例似乎有每个属性(值为Dummy)。

因此,Noneinspect.isclass似乎是一个类。

注意:__getattr__ should raiseAttributeError when asked for an attribute it does not know about.(这与返回foo非常不同。)

答案 1 :(得分:4)

首先,如果所有伟大的答案Jon-Eric我只是想添加一些东西:

如果你在ipython中做(这是一个很棒的工具):

%psource inspect.isclass

你会得到:

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

这是Jon-Eric所说的。

但我想你使用的是python&lt; 2.6并且这个bug已经修复,这是python2.7中的inspect.isclass()代码:

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