是否有可能创建任何不可排序的python对象?那么在尝试对这些对象列表进行排序时会出现异常吗? 我创建了一个非常简单的类,没有定义任何比较方法,但是这个类的实例仍然具有可比性,因此可以排序。也许,我的类从某个地方继承了比较方法。但我不想要这种行为。
答案 0 :(得分:7)
您可以在类上定义__cmp__
方法,并在调用时始终引发异常。这可能会成功。
出于好奇,为什么?
答案 1 :(得分:1)
正如Will McCutchen所提到的,您可以定义一个__cmp__
方法,该方法会引发异常以防止花园种类排序。像这样:
class Foo(object):
def __cmp__(self, other):
raise Exception()
a = [Foo(), Foo(), Foo()]
a.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __cmp__
Exception
但是,您无法真正阻止开发人员对对象列表进行排序。使用key
或cmp
参数与list.sort()
或内置的独立sorted()
函数,任何人都可以通过使用自定义比较函数绕过__cmp__
方法或排序键。
# continuing from above
>>> a = [Foo(), Foo(), Foo()]
>>> a
[<__main__.Foo object at 0x1004a3350>, <__main__.Foo object at 0x1004a3390>,
<__main__.Foo object at 0x1004a33d0>]
>>> a.sort(key=id, reverse=True)
>>> # or a.sort(cmp=lambda a, b: cmp(id(b), id(a)))
>>> # or sorted(a, key=id)
>>> # etc...
[<__main__.Foo object at 0x1004a33d0>, <__main__.Foo object at 0x1004a3390>,
<__main__.Foo object at 0x1004a3350>]
正如其他人会指出的那样,我不确定试图阻止某人对某个对象进行排序有多大价值。如果这不只是一个奇怪的痒,你试图划伤,这是什么用例?
答案 2 :(得分:1)
默认列表排序在其元素上使用内置的cmp()
函数。 cmp()
函数检查其参数(列表中的2个元素)是否具有__cmp__()
方法。如果是,则使用此方法进行比较。否则,就像你的情况一样,参数对象ID(内置函数id()
的返回值)用于比较。
要让排序失败,您可以定义一个抛出异常的比较方法:
>>> class X(object):
... def __cmp__(self, other):
... raise StandardError # or whatever Exception you need
...
>>> l = [X(), X(), X()]
>>> l.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in __cmp__
StandardError
答案 3 :(得分:1)
对于它的价值,在Python 3中,默认将是新项目无法比较(因此不可排序)。在Python 2中,您必须明确地创建__cmp__
或__lt__
方法,正如其他人所说的那样。
答案 4 :(得分:0)
为什么不编写一个包含列表对象的类并提供访问内部数据的方法?通过这样做,您将有效地隐藏列表,从而阻止它们对其进行排序。
答案 5 :(得分:0)
集合没有总排序
>>> s=set((1,2,3))
>>> t=set("abc")
>>> s<t
False
>>> t<s
False
>>>
但是,当您尝试对它们进行排序时,不会出现异常
>>> sorted([s,t])
[set([1, 2, 3]), set(['a', 'c', 'b'])]
答案 6 :(得分:0)
python排序算法使用__lt__
特殊方法。请记住,使用排序函数和方法的cmp
和key
参数,建议您的类定义一个方法:
def __lt__(self, other):
raise NotImplementedError