用Python初始化模块级列表的最清晰方法



我遇到了一种情况,模块需要进行一些简单但稍微耗时的初始化。结束条件之一是将由初始化填写的一对列表;困扰我的是,列表的角色(基本上是常量)和实际初始化它们的需要之间存在冲突。

我觉得写这样的代码很不舒服:

CONSTANT_LIST = []
DIFFERENT_LIST = []
for item in get_some_data_slowly():
if meets_criteria_one(item): 
CONSTANT_LIST.append(item)
continue
if meets_criteria_two(item):
DIFFERENT_LIST.append(item)

由于普通读者会在通常由常量占据的位置看到这些列表,并可能认为它们是空的。

OTOH,如果我能把这写为一个列表理解,我对同样的幕后事实也没意见:

CONSTANT_LIST = [i for i in some_data() if criterion(i)]

等等…除了我需要从同一个(稍微耗时)源中提取两个列表之外,所以两个列表的理解会使代码明显变慢。

更糟糕的是,应用程序将常量隐藏在方法后面:

__private_const_list = None
__other_private_list = None
def public_constant_list():
if __private_const_list: return  __private_const_list 
# or do the slow thing now and fill out both lists...
# etc
def public_other_const_list():
# same thing

有点傻,因为可能的使用频率基本上是每个会话1次。

正如你所看到的,这不是一个火箭科学问题,但我对Python的感觉一点也不刺痛。这里合适的蟒蛇图案是什么?

循环非常清晰。不要因为太聪明而混淆它。只需使用注释来帮助解释

CONSTANT_LIST = []    # Put a comment here to tell the reader that these 
DIFFERENT_LIST = []   # are constants that are filled in elsewhere
"""
Here is an example of what CONSTANT_LIST looks like
...
Here is an example of what DIFFERENT_LIST looks like
...
"""

for item in get_some_data_slowly():
if meets_criteria_one(item): 
CONSTANT_LIST.append(item)
elif meets_criteria_two(item):
DIFFERENT_LIST.append(item)

可能使用elif而不是continue/if

相关内容

  • 没有找到相关文章

最新更新