如何使一个整数大于任何其他整数?

注意:虽然接受的答案达到了我想要的结果,而@ecatmur答案提供了一个更全面的选项,但我觉得强调我的用例首先是一个坏主意是非常重要的。 这在下面的@Jason Orendorff答案中得到了很好的解释。

注意:这个问题不是关于sys.maxint的问题的重复。 它与sys.maxint ; 即使在python 2中sys.maxint可用,它不代表最大的整数(见接受的答案)。

我需要创build一个大于任何其他整数的整数,这意味着一个int对象,当使用>来比较任何其他int对象时,它将返回True 。 用例:库函数需要一个整数,而强制某个行为的唯一简单方法是传递一个非常大的整数。

在Python 2中,我可以使用sys.maxint (编辑:我错了)。 在python 3中, math.inf是最接近的等价物,但我不能将其转换为int

由于Python整数是无限的,你必须用一个自定义的类来做到这一点:

 import functools @functools.total_ordering class NeverSmaller(object): def __le__(self, other): return False class ReallyMaxInt(NeverSmaller, int): def __repr__(self): return 'ReallyMaxInt()' 

在这里,我使用了混合类NeverSmaller而不是直接修饰ReallyMaxInt ,因为在Python 3中functools.total_ordering的行为已经被从intinheritance的现有sorting方法阻止了。

用法演示:

 >>> N = ReallyMaxInt() >>> N > sys.maxsize True >>> isinstance(N, int) True >>> sorted([1, N, 0, 9999, sys.maxsize]) [0, 1, 9999, 9223372036854775807, ReallyMaxInt()] 

注意,在python2中, sys.maxint + 1sys.maxint ,所以你不能依赖它。

免责声明 :这是一个在OO意义上的整数,它不是math意义上的整数。 因此,从父类intinheritance的算术运算可能不会有合理的performance。 如果这会导致您的预期用例出现任何问题,那么可以通过实现__add__和朋友来禁用它们,只是出错。

Konsta Vesterinen的infinity.Infinity会工作( pypi ),除了它不从intinheritance,但是你可以inheritance它:

 from infinity import Infinity class IntInfinity(Infinity, int): pass assert isinstance(IntInfinity(), int) assert IntInfinity() > 1e100 

另一个实现“无限”价值的scheme是Extremes ,它是从被拒绝的PEP 326中拯救出来的; 再次,你需要从extremes.Maxint

用例:库函数需要一个整数,而强制某个特定行为的唯一简单方法是传递一个非常大的整数。

这听起来像是应该在其界面中修复的库中的缺陷。 那么所有的用户都将受益。 它是什么库?

用重写的比较运算符创build一个神奇的int子类可能适合你。 虽然这很脆弱 你永远不知道图书馆将如何处理这个对象。 假设它将它转换为一个string。 应该发生什么? 数据自然地以图书馆发展的不同方式使用; 你可能会更新图书馆一天,发现你的伎俩不工作了。

在我看来,这将是根本不可能的。 比方说,你写一个函数,返回这个打点(“真的大int”)。 如果计算机能够存储它,则其他人可以编写一个返回相同值的函数。 你的RBI比自己大吗?

也许你可以用@ wim的回答来达到理想的结果:创build一个覆盖比较运算符的对象,使得“<”总是返回false,“>”总是返回true。 (我没有写很多Python,在大多数面向对象的语言中,只有在比较把你的值放在第一位的时候才会起作用,如果有人用比较的方式写出IF IF> RBI,将会失败,因为编译器不知道如何将整数与用户定义的类进行比较。)

在Python 3.5中,你可以这样做:

import math test = math.inf

接着:

test > 1 test > 10000 test > x

永远是真的 当然,除非指出,x也是无穷大或“南”(“不是数字”)。

我如何在Python中表示无限数字?

由@WilHall回答

你不应该从intinheritance,除非你想要它的接口和它的实现 。 (它的实现是一个自动扩展的代表有限数字的位,你显然不需要这个)。既然你只想要接口 ,那么就从ABC Integralinheritance。 感谢@ ecatmur的回答,我们可以使用infinity来处理infinity的本质(包括否定)。 以下是我们如何将infinity与ABC Integral相结合:

 import pytest from infinity import Infinity from numbers import Integral class IntegerInfinity(Infinity, Integral): def __and__(self, other): raise NotImplementedError def __ceil__(self): raise NotImplementedError def __floor__(self): raise NotImplementedError def __int__(self): raise NotImplementedError def __invert__(self, other): raise NotImplementedError def __lshift__(self, other): raise NotImplementedError def __mod__(self, other): raise NotImplementedError def __or__(self, other): raise NotImplementedError def __rand__(self, other): raise NotImplementedError def __rlshift__(self, other): raise NotImplementedError def __rmod__(self, other): raise NotImplementedError def __ror__(self, other): raise NotImplementedError def __round__(self): raise NotImplementedError def __rrshift__(self, other): raise NotImplementedError def __rshift__(self, other): raise NotImplementedError def __rxor__(self, other): raise NotImplementedError def __trunc__(self): raise NotImplementedError def __xor__(self, other): raise NotImplementedError def test(): x = IntegerInfinity() assert x > 2 assert not x < 3 assert x >= 5 assert not x <= -10 assert x == x assert not x > x assert not x < x assert x >= x assert x <= x assert -x == -x assert -x <= -x assert -x <= x assert -x < x assert -x < -1000 assert not -x < -x with pytest.raises(Exception): int(x) with pytest.raises(Exception): x | x with pytest.raises(Exception): ceil(x) 

这可以用pytest运行来validation所需的不variables。

另一种做法(非常受wim的答复启发)可能是一个不是无限的对象,而是根据需要随时增加。

以下是我的想法:

 from functools import wraps class AlwaysBiggerDesc(): '''A data descriptor that always returns a value bigger than instance._compare''' def __get__(self, instance, owner): try: return instance._compare + 1 except AttributeError: return instance._val def __set__(self, instance, value): try: del instance._compare except AttributeError: pass instance._val = value class BiggerThanYou(int): '''A class that behaves like an integer but that increases as needed so as to be bigger than "other" values. Defaults to 1 so that instances are considered to be "truthy" for boolean comparisons.''' val = AlwaysBiggerDesc() def __getattribute__(self, name): f = super().__getattribute__(name) try: intf = getattr(int,name) except AttributeError: intf = None if f is intf: @wraps(f) def wrapper(*args): try: self._compare = args[1] except IndexError: self._compare = 0 # Note: 1 will be returned by val descriptor new_bigger = BiggerThanYou() try: new_bigger.val = f(self.val, *args[1:]) except IndexError: new_bigger.val = f(self.val) return new_bigger return wrapper else: return f def __repr__(self): return 'BiggerThanYou()' def __str__(self): return '1000...' 

像这样的东西可能会避免一个人可能不会期望的怪异行为。 请注意,用这种方法,如果一个操作涉及两个BiggerThanYou实例,那么LHS将被认为比RHS更大。

编辑:目前这是不工作 – 我会稍后修复它。 似乎我正在被特殊的方法查找function咬伤。