【问题标题】:why does python inspect.isclass think an instance is a class?为什么 python inspect.isclass 认为一个实例是一个类?
【发布时间】:2010-11-02 20:30:10
【问题描述】:

给定以下模块:

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

【问题讨论】:

    标签: python introspection


    【解决方案1】:

    在 Python v2.7 之前,inspect.isclass 天真地假设任何具有 __bases__ 属性的东西都必须是一个类。

    Dummy__getattr__ 使Dummy 实例看起来具有every 属性(值为None)。

    因此,对于inspect.isclassfoo 似乎是一个类。

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

    【讨论】:

    • 尤其是缺少AttributeError,这将导致真正惊人的可怕错误。
    • 谢谢。您的解释完全有道理。
    【解决方案2】:

    首先,如果所有答案都很好 Jon-Eric,我只是想添加一些东西:

    如果你使用 ipython(多么棒的工具):

    %psource inspect.isclass
    

    你会得到:

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

    Jon-Eric 所说的。

    但我猜你用的是python

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

    【讨论】:

    • 好点!我正在查看 v2.6 源代码。我编辑了我的答案以表明 __bases__ 在 v2.7+ 中不再使用。
    猜你喜欢
    • 2012-09-27
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    相关资源
    最近更新 更多