是否以及何时以及如何在python中存储len()
或sum()
的值的约定?举个例子,如果你有一个Class
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为诸如len
之类的某些任务省去了for my_numbers in multiple_numbers:
的使用,因此我不需要仅用于迭代。另外,对于类的实例,len
的值是静态的,并且在运行时的不同部分(可能)需要多次(因此),因此它不是临时变量like here。通常,这似乎是(非常少量的)内存与计算之间的折衷。相同的问题适用于sum()
。
这些问题的某些部分是基于观点的,很高兴听到您对此的看法,但我主要是在寻求有关此问题的约定。
len(self.multiple)
存储为自己的值?length_of_multiple_numbers
似乎很肿胀,但具有描述性。我将使用局部变量,更多的是为了代码可读性而不是速度:
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 len_
def len_(self):
return len(self) #it's a list
or
_len_ = None
@property len_
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.
同样,如果您缓存它,则需要确保每次结果更改时都要重置缓存。这也是您存储在实例变量上的想法的弱点-确保您没有过时的数据所带来的额外复杂性可能只有在您确定这确实是性能瓶颈后才可以接受。
(在您的示例中,mutable default argument的使用multiple_numbers
不能解决这些问题,顺便说一句]
命名方式上,我可能会采用半常规命名方式,以避免遮盖内置/常规名称,即添加_
:cls
-> cls_
,list
-> [C0 ]。