首页 > 解决方案 > 添加或读取时处理数据

问题描述

哪种方式更适合python风格:

class Foo:
    def __init__(self):
        self.sorted_elements = []

    def add_element(self, element):
        self.sorted_elements.append(element)
        self.sorted_elements.sort()

    def read_elements(self):
        for element in self.sorted_elements:
            do_something(element)

或者

class Foo:
    def __init__(self):
        self.elements = []

    def add_element(self, element):
        self.elements.append(element)

    def read_elements(self):
        for element in sorted(self.elements):
            do_something(element)

我们应该什么时候处理我们的数据?当我们收集它或当我们用它做某事时?当然,一个人可以发表声明,这取决于我们做的更多,添加或阅读。但是,如果我们必须制定经验法则,那会是什么?恕我直言,我倾向于第二种方式,因为它保证正确的顺序而不依赖于某些外部状态。

标签: python

解决方案


这些解决方案都没有比其他解决方案更多或更少的pythonic,并且都有利有弊,具体取决于您的典型用例。两者都有几个问题......

  • 如果连续添加数千个数据,第一个解决方案效率非常低

  • 第二个继续对列表进行排序,大多数情况下,该列表已经排序。鉴于 Python 的内置排序算法行为,这应该不是一个大问题,但这仍然是一些函数调用,它们不是免费的。

  • 在这两种情况下,elements作为公共属性公开会破坏封装并使整个问题变得毫无意义,因为任何人都可以添加.elements而不对其进行排序或读取.elements而不对其进行排序...

因此,首先要做的实际上是elements私有化。然后你想跟踪是否_elements需要排序:

class Foo:

    def __init__(self):
        self._elements = []
        self._sorted = True

    def add_element(self, element):
        self._elements.append(element)
        self._sorted = False

    def read_elements(self):
        if not self._sorted:
            self._elements.sort() 
            self._sorted = True

        for element in self._elements:
            do_something(element)

现在你有一个正确封装的实现,只在必要时排序......


推荐阅读