自定义实例方法排序的预期行为

时间:2018-01-10 19:07:54

标签: python python-2.7

在Python 2.7中,list个对象实现了一个sort方法,它采用了cmpkeyreverse三个参数,如{{3}所述(见注释8),前两个默认为值None,最后一个默认为False

假设有人对实现一个提供名为sort的实例方法的类感兴趣,该方法具有相同的签名,即采用与list.sort相同的参数。对于list.sortcmpkey参数可能会导致列表中的不同顺序被排序,因此可能不兼容。

我的问题是,在sortcmpkey不同的情况下,实施实例方法None时是否应该遵循最佳做法?

为清楚起见,请考虑以下示例方案:

class Table(object):

    """Stores data by rows."""

    def __init__(self, *rows):
        self._rows = list(rows)

    def sort(self, cmp=None, key=None, reverse=False):
        """Sort table rows."""

        if cmp and key:
            # What behaviour would an experienced Python programmer
            # expect in this situation? Raise a ValueError? Prefer
            # one of cmp and key? Or is there no best practice here?
            raise ValueError('I am partial to raising a ValueError.')

        # The implementation could be more involved than pushing the
        # call to sort forward to self._rows, for instance if data was
        # stored by columns.
        self._rows.sort(cmp, key, reverse)

注意:此处提出的问题不是Python 3.6中的问题,cmphere)不支持参数list.sort。< / p>

1 个答案:

答案 0 :(得分:2)

我认为这个前提在这里有点瑕疵:

  

对于list.sortcmpkey参数可能会导致列表中的不同订单被排序,因此可能不兼容。

cmpkey通常不兼容,因为它们会做不同的事情。 key定义了如何将列表成员映射到它们将按其排序的值,cmp定义了如何确定这两个值的相对顺序。使用两者都非常有效(尽管很少有好主意):

>>> mylist = [(2, 'two'), (3, 'three'), (7, 'seven')]
>>> mylist.sort(key=lambda a:a[1], cmp=lambda a,b:ord(a[-1])-ord(b[-1]))
>>> mylist
[(3, 'three'), (7, 'seven'), (2, 'two')]

我已经按照第二项的最后一个字母对列表进行了排序。我本可以单独使用cmpkey来完成这项工作(而这些天的建议是使用key),但如果我真的想这样做,那么两种工作都可以。< / p>

所有这一切,你的sort方法只是一个用于排序内部列表的包装器的例子看起来非常简单。如果要匹配内置list.sort()的功能,为什么要进行任何验证?直接通过所有内容:

def sort(self, *args, **kwargs):
    self._rows.sort(*args, **kwargs)