int和numbers之间的区别.Python中的整数

Ele*_*naT 12 python

我试图深入了解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 intclass numbers.Integral我在上面的输出中看到的vs 有什么关系吗?

Cat*_*lus 10

numbers定义抽象类的层次结构,定义数值类型可能的操作.见PEP 3141.int和之间的区别Integral是,它int是支持所有操作Integral定义的具体类型.

  • @ElenaT:`number.Integral`是一个模型(或概念).`int`是该模型的一个实现.这就是他们的相关方式.继承与问题正交. (4认同)

Rob*_*mer 5

请允许我补充两件事:

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

  • 如果您子类化 `int` (或 Python 2 上的 `long`),则 `isinstance(subclass_instance, (int, long))` 仍然为 true。区别在于,如果您正在使用另一个定义所有相同方法但不继承自“int”或“long”的 Integral 类型,例如 numpy 整数。`isinstance(np.int64(), (int, long)` 将始终为 False,而 `isinstance(np.int64(), Numbers.Integral)` 将返回 True。 (4认同)

Mis*_*agi 5

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定义。