Python中的sorted()有神奇的方法吗?

Python中的sorted()有神奇的方法吗?,python,oop,magic-methods,Python,Oop,Magic Methods,我知道python中有一些神奇的方法可以被类覆盖,以控制某些内置函数处理这些类成员的方式。例如,len() 还有\uu cmp\uu()和\uu ge\uuu(),\uu le\uu()等方法来控制如何比较这些对象,以及如何按list.sort()对它们的列表进行排序。我的问题不是定制列表中对象的顺序,而是对对象本身进行排序。假设集合不是空的,我想使用sorted()对其进行排序: class SetOfTwo(object): def __init__(self, a , b):

我知道python中有一些神奇的方法可以被类覆盖,以控制某些内置函数处理这些类成员的方式。例如,
len()

还有
\uu cmp\uu()
\uu ge\uuu()
\uu le\uu()
等方法来控制如何比较这些对象,以及如何按
list.sort()
对它们的列表进行排序。我的问题不是定制列表中对象的顺序,而是对对象本身进行排序。假设集合不是空的,我想使用
sorted()
对其进行排序:

class SetOfTwo(object):
    def __init__(self, a , b):
        el_0 = a
        el_1 = b

    def __len__(self):
        return 2

    def __str__(self):
        return '[{}, {}]'.format(el_0, el_1)
是否有一种神奇的方法可以让
排序()
在元素不按顺序排列时翻转它们?我正在想象以下行为:

>>> s = SetOfTwo(2, 1)
>>> str(s)
[2, 1]

>>> t = sorted(s)
>>> str(t)
[1, 2]

>>> type(t)
>>> SetOfTwo

您肯定应该了解如何模拟容器类型。基本上,假定用作容器的类(列表、dict等)需要实现方法来设置或获取成员
\uuu getitem\uuuuuuuu()
\uuuuuuu setitem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
,并迭代项
\uuuuuuuuuuuuuuuuuuuuuuuuuuuu()
。这是最低限度。但您也可以添加删除项目和其他操作的功能


sorted()
内置函数的行为是迭代容器的元素,并使用您提到的
\uuuuCMp\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(),\uuuuuuuuu ge\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。然后创建一个新的
列表
实例,并对项目进行排序,然后返回这个新实例。您可以将其传递给自定义容器的构造函数,也可以使用自定义函数编写
sorted()
,该函数将返回所需的类实例。

正如一些人在评论中所说,集合是无序的,但我认为您的问题并不真正与集合有关

Python使用您提到的数据模型方法,gelecmp来确定调用sorted()时类的行为。您可以看到我如何尝试在这里调用它,但是Python对象并要求我实现>>类a(对象): ... 通过 ... >>>b=a() >>>c=a() >>>d=[b,c] >>>分类(d) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:“
len()
str()
是将对象作为参数并返回整数(分别为字符串)的函数。该对象可以通过
\uuu len\uuu()
\uu str\uuu()
魔术方法对len的计算方式或字符串的生成方式进行个性化设置

类似地,
sorted()
是一个函数,它获取对象列表(或任何iterable)并返回排序对象列表。对象可以通过
\uu lt\uuu()
魔术方法对它们进行比较的方式进行个性化设置

当我们将“排序(my_list)”视为“对列表排序”的函数,而不是“对列表中的元素排序”时,就会产生一些混淆


您不想对对象进行排序(即,制作一个有序的对象列表),而只对其内部表示形式中的某些数据进行排序。因此,您需要在对象上使用一个实例方法来更新该内部表示。如果愿意,您可以将其命名为,
.sort()
,但您必须在一个对象上调用它,并且它不会参与对象比较。

集合本身就是无序的。看见至于您的实际问题(除了术语),只需在类上定义您自己的排序方法并使用它即可。或者传入一个lamda。@JaredSmith我不认为这个问题是关于集合的。你可以试试OrderedSetI。很抱歉在我的玩具示例中使用了一个天生无序的集合。希望python中是否有一个神奇的sorted()方法的问题仍然很清楚,python函数接受一个iterable并返回一个列表。因此,如果集合支持迭代,则可以将其传递到
sorted()
。元素的顺序基于其自然顺序或传递给
sorted()
的键函数。您将返回一个列表,而不是自定义类型。指向模拟容器类型的链接非常有用。基本上,如果有一种神奇的排序方法,它会出现在官方文档中,名为
\uuuuuuu sorted\uuuuuu()
。我几乎问了这个关于
reversed()
的问题,而那个页面确实列出了一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。因此,有一种神奇的方法可以实现您自己的
reversed()
行为,而不是
sorted()
。在阅读文档的正确部分之前,这一点并不明显。这是因为撤销集合并不关心项的值,而是根据这些值对其进行排序。在我看来,唯一重要的区别是
reversed()
在容器中查找
\u reversed\u()
方法,而
已排序()
不寻找
\uuuuu排序的方法。
这是技术上的区别-你是对的。但是Python开发人员以这种方式实现它的原因,我在上一篇评论中解释过。你可以想象一个类,它在某种程度上对项目进行排序而不进行比较,但它不能被称为“排序”。还有其他原因需要覆盖排序。例如,我可能想添加一个issorted标志,该标志跳过排序算法,并返回一个对象的副本(如果已知该对象以前已排序)。您能解释一下如何在不进行排序的情况下对任何内容进行排序吗?@ElmoVanKielmo也许我的意思用示例:在问题中,OP希望对
SetOfTwo
对象中的
el_0
el_1
属性进行排序(他表示为
>>> s = SetOfTwo(2, 1)
>>> str(s)
[2, 1]

>>> t = sorted(s)
>>> str(t)
[1, 2]

>>> type(t)
>>> SetOfTwo
>>> class a(object):
...   pass
...
>>> b = a()
>>> c = a()
>>> d = [b, c]
>>> sorted(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'a' and 'a'