Python 中是否有 sorted() 的神奇方法?
is there a magic method for sorted() in Python?
我知道 python 中有魔法方法可以被 类 覆盖,以控制某些内置函数处理这些 类 成员的方式。例如,len()
和 str()
的行为可以通过魔术方法 __len__()
和 __str__()
:
覆盖
class EmptySet(object):
def __len__(self):
return 0
def __str__(self):
return '[]'
>>> e = EmptySet()
>>> str(e)
[]
>>> len(e)
0
还有 __cmp__()
和 __ge__()
、__le__()
等方法来控制如何比较这些对象以及如何按 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)
有没有我可以实现的神奇方法 sorted()
翻转不按顺序排列的元素?我正在描绘以下行为:
>>> s = SetOfTwo(2, 1)
>>> str(s)
[2, 1]
>>> t = sorted(s)
>>> str(t)
[1, 2]
>>> type(t)
>>> SetOfTwo
您绝对应该阅读 the official documentation 如何模拟容器类型。基本上,一个 class 应该作为容器(列表、字典等)工作需要实现方法来设置或获取成员 __getitem__()
、__setitem__()
并迭代项目 __iter__()
和获取项目的数量 - 方法 __len__()
。 这是最低要求。但是你也可以添加删除项目等操作的能力。
sorted()
built-in 函数的行为是迭代容器的元素并使用您提到的方法比较它们 __cmp__(), __ge__(), __le__()
应该为项目而不是容器定义为你已经知道了。然后创建一个新的 list
实例,其中的项目已排序,并且这个新实例是 returned。然后您可以将它传递给自定义容器的构造函数,或者您可以使用自定义函数包装 sorted()
,这将 return 所需的 class 实例。
正如某些人在评论中所说,集合是无序的,但我认为您的问题并不是关于集合的。
Python 使用您提到的数据模型方法,ge、le 和 cmp 来确定 class 在调用 sorted() 时的行为。你可以在这里看到我是如何尝试调用它的,但是 Python 反对并要求我实现 <.
>>> 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'
希望这对您有所帮助。另外,正如其他人所说,将 collections.abc 中的某些内容子 class 是个好主意。我阅读了 effective python 中的第 28 条,其中讨论了这个问题以获得一个好主意。
len()
和 str()
是将对象作为参数的函数,return 是整数(分别为字符串)。该对象可以通过 __len__()
和 __str__()
魔术方法个性化计算 len 或生成字符串的方式。
类似地,sorted()
是一个接受对象列表(或任何可迭代对象)和 returns 排序对象列表的函数 。这些对象可以通过 __lt__()
魔术方法个性化比较它们的方式。
当我们将 `sorted(my_list) 视为 "sorts the list" 而不是 "sorts the elements of the list".
的函数时,会出现一些混淆
您不想对您的对象进行排序(即制作一个有序的对象列表),而只是对一些数据的内部表示进行排序。因此,您需要在对象上使用一个实例方法来更新该内部表示。你可以随意命名,.sort()
如果你喜欢,但是你必须在你的一个对象上调用它,它不会参与比较对象。
我知道 python 中有魔法方法可以被 类 覆盖,以控制某些内置函数处理这些 类 成员的方式。例如,len()
和 str()
的行为可以通过魔术方法 __len__()
和 __str__()
:
class EmptySet(object):
def __len__(self):
return 0
def __str__(self):
return '[]'
>>> e = EmptySet()
>>> str(e)
[]
>>> len(e)
0
还有 __cmp__()
和 __ge__()
、__le__()
等方法来控制如何比较这些对象以及如何按 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)
有没有我可以实现的神奇方法 sorted()
翻转不按顺序排列的元素?我正在描绘以下行为:
>>> s = SetOfTwo(2, 1)
>>> str(s)
[2, 1]
>>> t = sorted(s)
>>> str(t)
[1, 2]
>>> type(t)
>>> SetOfTwo
您绝对应该阅读 the official documentation 如何模拟容器类型。基本上,一个 class 应该作为容器(列表、字典等)工作需要实现方法来设置或获取成员 __getitem__()
、__setitem__()
并迭代项目 __iter__()
和获取项目的数量 - 方法 __len__()
。 这是最低要求。但是你也可以添加删除项目等操作的能力。
sorted()
built-in 函数的行为是迭代容器的元素并使用您提到的方法比较它们 __cmp__(), __ge__(), __le__()
应该为项目而不是容器定义为你已经知道了。然后创建一个新的 list
实例,其中的项目已排序,并且这个新实例是 returned。然后您可以将它传递给自定义容器的构造函数,或者您可以使用自定义函数包装 sorted()
,这将 return 所需的 class 实例。
正如某些人在评论中所说,集合是无序的,但我认为您的问题并不是关于集合的。
Python 使用您提到的数据模型方法,ge、le 和 cmp 来确定 class 在调用 sorted() 时的行为。你可以在这里看到我是如何尝试调用它的,但是 Python 反对并要求我实现 <.
>>> 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'
希望这对您有所帮助。另外,正如其他人所说,将 collections.abc 中的某些内容子 class 是个好主意。我阅读了 effective python 中的第 28 条,其中讨论了这个问题以获得一个好主意。
len()
和 str()
是将对象作为参数的函数,return 是整数(分别为字符串)。该对象可以通过 __len__()
和 __str__()
魔术方法个性化计算 len 或生成字符串的方式。
类似地,sorted()
是一个接受对象列表(或任何可迭代对象)和 returns 排序对象列表的函数 。这些对象可以通过 __lt__()
魔术方法个性化比较它们的方式。
当我们将 `sorted(my_list) 视为 "sorts the list" 而不是 "sorts the elements of the list".
的函数时,会出现一些混淆您不想对您的对象进行排序(即制作一个有序的对象列表),而只是对一些数据的内部表示进行排序。因此,您需要在对象上使用一个实例方法来更新该内部表示。你可以随意命名,.sort()
如果你喜欢,但是你必须在你的一个对象上调用它,它不会参与比较对象。