是否有任何类型的“陷阱”与一个列表或任何其他可变对象的常量相关联?
目前我的上下文与将传递给调用的常量有关,但我一般都会问这个问题,因为我不认为该主题会对问题产生有意义的影响。
考虑这个示例代码:
#!/usr/bin/env python
# This file was not tested before posting.
import subprocess
LS_FLAGS = ['-l', '-a']
def main():
subprocess.call(['ls'] + LS_FLAGS)
if __name__ == '__main__':
main()
我问这个是因为我对mutable objects in function definitions所产生的问题一无所知。并且,即使我理解,也不应该有任何事情进行任务或突变到一个受尊重的常数;并且“常数”并不是真正的东西:我问,并且进一步问,是否可能存在一些语义上保护自我的惯例不是偶然的突变?
答案 0 :(得分:2)
不必担心变异可以使代码更易于推理,因此,它是纯函数式编程的核心原则之一。
在这种特殊情况下,它似乎不是一个严重的问题,甚至可能被认为是一个特征。如果您觉得没有理由可以修改LS_FLAGS
,则可以随时将其定义为元组,但如果您愿意,代码的用户可以完全重新声明LS_FLAGS
。
答案 1 :(得分:0)
您可以通过从类字典对象访问“常量”来防止变异。有点像''那样',或许:
class Config:
_config = dict(
LS_FLAGS=['-l', '-a']
)
def __getitem__(self, idx):
return Config._config[idx].copy() # Use copy.deepcopy
# instead if required
CONFIG=Config()
甚至:
class Config:
def __getitem__(self, idx):
if idx == 'LS_FLAGS':
return ['-l', '-a']
raise KeyError(idx)
CONFIG=Config()
然后使用CONFIG
这样的对象:
print(CONFIG['LS_FLAGS'])
这远非完美(并且不是很性感),但这会阻止意外 1 废弃你的“常数”:
# Try to mutate the constant config
ls_flags = CONFIG['LS_FLAGS']
ls_flags.append('/home')
print(CONFIG['LS_FLAGS']) # unchanged
和
CONFIG['LS_FLAGS'] = ['-ls']
将举起TypeError: 'Config' object does not support item assignment
¹当然,由于Python没有“真正的”常量,因此无法保护您免受恶意代码的攻击。例如,可以完全替换CONFIG
对象...