Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中,如何知道是否可以比较对象?_Python_Python 3.x_Comparison Operators_Abstract Base Class - Fatal编程技术网

在Python中,如何知道是否可以比较对象?

在Python中,如何知道是否可以比较对象?,python,python-3.x,comparison-operators,abstract-base-class,Python,Python 3.x,Comparison Operators,Abstract Base Class,通过使用,Python提供了一种了解对象行为的方法,而无需实际尝试。在标准库中,我们为中的容器定义了一些ABC。例如,可以测试一个参数是否可iterable: from collections.abc import Iterable def function(argument): if not isinstance(argument, Iterable): raise TypeError('argument must be iterable.') # do stu

通过使用,Python提供了一种了解对象行为的方法,而无需实际尝试。在标准库中,我们为中的容器定义了一些ABC。例如,可以测试一个参数是否可iterable:

from collections.abc import Iterable
def function(argument):
    if not isinstance(argument, Iterable):
        raise TypeError('argument must be iterable.')
    # do stuff with the argument
我希望会有这样一个ABC来决定是否可以比较类的实例,但找不到。测试
方法的存在性是不够的。例如,无法比较词典,但仍定义了
\uu lt\uu
(实际上与
对象相同)


不,没有这样的ABC,因为ABC只规定有哪些属性。ABC无法测试实现的性质(或者即使这些属性实际上是方法)

比较方法(
的存在并不意味着该类将与其他类具有可比性。通常,您只能比较相同类型或类型类别的对象;以数字为例

因此,大多数类型*实现比较方法,但在与其他不兼容类型进行比较时返回
NotImplemented
sentinel对象。返回
NotImplemented
会向Python发出信号,让右边的值在这个问题上也有发言权。如果
a.\uu lt\uuu(b)
返回
NotImplemented
,则
b.\uu gt\uu(a)
也会被测试

基本
对象
为方法提供默认实现,返回
NotImplemented

>>> class Foo:
...     pass
... 
>>> Foo() < Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: Foo() < Foo()
>>> Foo().__lt__
<method-wrapper '__lt__' of Foo object at 0x10f1cf860>
>>> Foo().__lt__(Foo())
NotImplemented
但是,当其他类型不可比较时,数字仅返回
NotImplemented

>>> (1).__lt__(2)
True
>>> (1).__lt__('2')
NotImplemented
>>> 1 < 2
True
>>> 1 < '2'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
>>>(1)。\uuult\uuuuuuu2
真的
>>>(1)———————————————————————————————————————————————————————————————————————
未实施
>>> 1 < 2
真的
>>> 1 < '2'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:无序类型:int()
因此,您最好的选择是捕获值不可比较时抛出的
TypeError



*我不知道Python3标准库中有任何类型目前没有实现比较方法。

ABCs不仅说明有哪些属性。这是他们可以强制执行的所有内容,但由于他们是选择性加入(需要从中继承或明确注册),大多数ABC可以并且确实定义了合同。当
是instance(x,abc.Sized)
时,假设
x.\uu len\uuu
是一个返回非负整数的方法是非常合理的。当然,它不是以编程的方式检查的,但是由于Python是动态的,所以实际上什么都不能检查。@delnan:当然,这是ABCs的意图。但是,由于比较方法的约定是在传递不兼容的对象类型时返回
NotImplemented
,因此无法使用ABCs测试该约定的实现程度。的确,双重分派使其更加复杂。我主要反对一般性的说法“只说明存在哪些属性”和(或者即使这些属性实际上是方法)。谢谢你的详细回答。你知道除了数字之外,还有很多对象可以与其他类型进行比较吗?@Fracis:在Python 2中,几乎所有类型都可以与其他类型进行比较;这是一个常见的错误源(特别是当涉及数字和字符串时);这样做是为了支持对异构序列进行排序。在Python3中,我目前想不出任何数字以外的例子(浮点数和整数有明确定义的顺序)。
>>> class Foo:
...     pass
... 
>>> Foo() < Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: Foo() < Foo()
>>> Foo().__lt__
<method-wrapper '__lt__' of Foo object at 0x10f1cf860>
>>> Foo().__lt__(Foo())
NotImplemented
>>> {}.__lt__({})
NotImplemented
>>> (1).__lt__(2)
True
>>> (1).__lt__('2')
NotImplemented
>>> 1 < 2
True
>>> 1 < '2'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()