我试图深入了解Python的数据模型,我不完全理解以下代码:
>>> x = 1
>>> isinstance(x,int)
True
>>> isinstance(x,numbers.Integral)
True
>>> inspect.getmro(int)
(<type 'int'>, <type 'object'>)
>>> inspect.getmro(numbers.Integral)
(<class 'numbers.Integral'>, <class 'numbers.Rational'>, <class 'numbers.Real'>,
<class 'numbers.Complex'>, <class 'numbers.Number'>, <type 'object'>)
Run Code Online (Sandbox Code Playgroud)
基于以上所述,它似乎int并且number.Integral不在同一层次结构中.
从Python参考(2.6.6)我看到
numbers.Integral - 这些表示来自整数的数学集合(正面和负面)的元素.
int和之间有什么区别numbers.Integral?它type int与class numbers.Integral我在上面的输出中看到的vs 有什么关系吗?
请允许我补充两件事:
isinstance(x,numbers.Integral)
Run Code Online (Sandbox Code Playgroud)
还涵盖long和
isinstance(x, int)
Run Code Online (Sandbox Code Playgroud)
才不是。测试numbers.Integral会更接近
isinstance(x, (int, long))
Run Code Online (Sandbox Code Playgroud)
在 Python 2 中(Python 3 被long永远杀死了。)
我更喜欢用 进行测试numbers.Integral,因为如果您从int(或long) 派生,isinstance(y, numbers.Integral)仍然会是True。
TLDR:int 注册为 的虚拟子类numbers.Integral。
# numbers.py:380 (CPython 3.8)
Integral.register(int)
Run Code Online (Sandbox Code Playgroud)
numbers.Integral是整数必须提供的抽象定义。int是整数的具体实现。
和isinstance函数issubclass不限于继承。例如,它们可以表达结构类型关系,例如collections.abc.Iterable:
>>> class MyIterable:
... def __iter__(self): ...
...
>>> issubclass(MyIterable, collections.abc.Iterable)
True
Run Code Online (Sandbox Code Playgroud)
事实上,每种类型isinstance和都issubclass可以更改。标准库使用它来定义抽象基类(ABC),支持具体子类(通过继承)和虚拟子类(通过)。cls.register(subclass)
虚拟子类不通过继承与它的 ABC 相关——因此它的方法解析顺序不使用 ABC。具体来说,int不继承任何方法numbers.Integral。然而,它确实实现了独立所需的所有公共方法和操作numbers.Integral- 从而满足了numbers.Integral定义。