【问题标题】:Why does isinstance(nonnewstyle, object) return true in Python 2.X?为什么 isinstance(nonnewstyle, object) 在 Python 2.X 中返回 true?
【发布时间】:2017-12-17 10:58:41
【问题描述】:

我正在阅读一本关于 Python 的教科书,它涵盖了新型类差异。在使用经典类的解释器中观察 Python 2.X 中的以下代码:

class C: pass
X = C()
isinstance(X, object) #returns true
isinstance(C, object) #returns true

(要使用新型类,必须显式从 2.X 中的对象类派生)

那么一个不从对象类派生的对象(如在经典类中的情况)如何成为对象的实例呢?在 3.X 和 2.X 的情况下,幕后发生了什么?

至于这是否是一个重复的问题:我已经知道从技术上讲一切都是一个对象,我想知道在 python 本身的设计中如何明确处理差异,而不是将 isinstance 的结果视为理所当然。

【问题讨论】:

标签: python-2.7 python-3.x types new-style-class


【解决方案1】:

您可能将isinstanceissubclass 混淆了。旧样式类不会派生object,这意味着issubclass(C, object) 的结果将是False。另一方面,新样式类始终包含object(直接或间接)作为基类。

一切都是object 的实例。所以isinstance(C, object)isinstance(x, object) 将永远是True

【讨论】:

    【解决方案2】:

    一切在 Python 中都是 object 的一个实例,包括 object 本身:

    >>> isinstance(object, object)
    True
    

    那是因为type.__instancecheck__ hook 在为object 传递self 时返回True,无论其他参数是什么(请记住,在type(something) 上查找特殊方法,而不是在something 本身上查找,并手动传入self)。

    如果您想测试旧式类,更有用的测试是该类是type 的实例,还是object子类

    >>> isinstance(C, type)
    False
    >>> issubclass(C, object)
    False
    

    这些测试中的任何一个都适用于新式类:

    >>> class Newstyle(object): pass
    ...
    >>> isinstance(Newstyle, type)
    True
    >>> issubclass(Newstyle, object)
    True
    

    例如,测试它们是否是types.InstanceType的实例:

    >>> isinstance(X, InstanceType)
    True
    

    【讨论】:

    • 我想我理解了一半,一切都是对象等等。但是东西怎么可能是对象的实例,而不是子类对象呢?
    • @user3751940:忘记对对象的实例检查;由于__instancecheck__ 挂钩,该测试是一个虚拟
    • 我现在明白了!谢谢:)
    【解决方案3】:

    X 是旧式类 C 的旧式实例,它不是 object 的子类。

    但是,所有对象,甚至是旧式实例,都是某种类型的实例(又名新式类)。所有旧式实例的类型为types.InstanceType;加上types.ClassType,旧式类的类型,这两个类型负责旧式类系统的实现。

    types.InstanceTypeobject 的子类,所有新式类也是如此。 isinstance(X, object) 返回 true 不是因为 X 的旧式类继承自 object,而是因为它的新式类继承。

    【讨论】:

      猜你喜欢
      • 2018-11-03
      • 2012-05-21
      • 2011-12-19
      • 2021-09-02
      • 2019-12-07
      • 2012-03-27
      • 2023-01-16
      • 1970-01-01
      相关资源
      最近更新 更多