python中将len()和sum()存储为变量的约定

2024-04-24 09:02:06 发布

您现在位置:Python中文网/ 问答频道 /正文

在python中是否有存储len()sum()值的时间和方式的约定?举个例子,如果你有一个类

class MyClass:

    def __init__(self, single_number = 4, multiple_numbers = [1,2,3]):
        self.single= single_number 
        self.multiple = multiple_numbers

    def info(self):
        print(f"The length of multiple is {len(self.multiple)}")
        print(f"The length of multiple is {len(self.multiple)*4}")
        print(f"The length of multiple is longer than {len(self.multiple)-1}")

if __name__ == "__main__":
    test=MyClass()
    test.info()
    # other stuff
    test.info()

在什么时候开始将len(self.multiple)存储为它自己的值?谢天谢地,python在某些任务(如for my_numbers in multiple_numbers:)中不使用len,因此我不需要它来进行迭代。此外,len的值对于类的实例是静态的,并且在运行时的不同部分需要(可能)多次,因此它不是临时变量like here。一般来说,这似乎是(非常少量的)内存与计算之间的折衷。同样的问题也适用于sum()

这些问题的一部分是基于意见的,我很高兴听到你们对它的看法,但我主要是希望就此达成一项公约

  1. 在什么时候,如果有的话,len(self.multiple)应该存储为它自己的值
  2. 这个名字有约定吗length_of_multiple_numbers看起来有些臃肿,但可能是描述性的

Tags: ofthetestselfinfolenisdef
2条回答

我会使用局部变量,更多的是为了代码可读性而不是速度:

def info(self):
    n = len(self.multiple)
    print(f"The length of multiple is {n}")
    print(f"The length of multiple is {n*4}")
    print(f"The length of multiple is longer than {n-1}")

局部变量名称可以很短,因为赋值与使用在同一屏幕上。我使用自己的约定,但它们通常遵循常见的非正式约定

我不会尝试将len(...)分配给self属性,更不用说全局属性了

基本上,在函数/方法中重复使用的任何值都是局部变量赋值的候选值

我不相信有太多的理由来证明存储,除非每次的计算成本都很高。参见hpaulj的答案

然而,如果你真的想,你可以使用一个属性,甚至可以缓存它

class MyList(list):

   @property
   def len_(self):
      return len(self)  #it's a list
or

   _len_ = None

   @property 
   def len_(self):
      if self._len_ is None:
          self._len_ = len(self)
      return self._len_

    def append(self, value):
       self._len_ = None
       super(MyList, self).append(value)

    ...and all other len-modifying methods also need to clear the cache.

同样,如果缓存它,则需要确保每次更改结果时都重置缓存。这也是您存储在实例变量上的想法的弱点——确保没有过时数据的额外复杂性可能只有在您确定这确实是一个性能瓶颈后才能接受

(顺便说一句,在您的示例中,对multiple_numbers使用mutable default argument对这些问题没有帮助)。一般来说,如果sum/len取决于可变项的状态,那么存储/缓存计算是一个更糟糕的想法。i、 e.如果MyList引用的对象本身具有需要聚合的len/sum,那么MyList就没有任何缓存/存储的业务

在命名方面,我可能会选择asemi-convention naming to avoid shadowing built-ins/conventional名称,即添加a_:cls->cls_list->list_

相关问题 更多 >