我想自定义一些代码。假设我想将一堆学生应用程序分配给暑期课程给各种读者(所以100个应用程序,3个读者,大致均匀划分等)。在某些情况下,我想考虑读者偏好(我只想阅读加州学生的申请等)。在其他情况下,我不关心他们被分配到谁。现在我有一些看起来像这样的东西:
def assign_readers(preferences_flag):
if preferences_flag:
assign_readers_with_preferences()
assign_remaining
我在我的代码中有多个类似功能的情况,我希望能够轻松打开/关闭,但它看起来不像是一种必要的干净方式。有时在代码的其他部分使用相同的标志,所以我左右传递这些标志。例如:
def log_reader_stats(preferences_flag, other_flag):
if preferences_flag:
log_reader_stats_with_preferences()
if other_flag:
log_readers_stats_with_other_stuff()
log_remaining_stats
这样做的替代方法是什么?传递标志似乎重复和低效,但除此之外,我不知道如何打开和关闭这些功能。
下面是一些如何使用实际代码以及标志如何发挥作用的示例。
USE_PREF = True
USE_SPEC_GRP = True
def main():
# Load and store config file information
fnames = {}
snames = {}
options = read_config_file()
validate_config_params(options, fnames, snames)
# Load the applications file
apps = pio.file_to_frame(fnames["apps"], snames["apps"])
# load target and max number of apps each reader can handle.
rdr_counts = pio.file_to_frame(fnames["rdr_counts"], snames["rdr_counts"])
# Assign applications depending on which options are enabled
if USE_SPEC_GRP:
assign_all_special_groups(apps, fnames["spec_grp"], snames["spec_grp"])
if USE_PREF:
assign_apps_with_prefs(apps, rdr_counts,
fnames["rdr_prefs"], snames["rdr_prefs"])
assign_remaining_apps(apps, rdr_counts, fnames, snames)
答案 0 :(得分:2)
虽然你没有提出这个问题,但有一个code smell需要解释。每当您发现自己使用fnames
和snames
等并行数据源时:
assign_all_special_groups(apps, fnames["spec_grp"], snames["spec_grp"])
您通常会制作容易出错的代码。相反,你可以
names['spec_grp'] = ('something', 'anotherthing')
确保spec_grp
的元素始终保持相互关联。存在namedtuple type,使访问非常易读:
names['spec_grp'].f_thing
names['spec_grp'].s_thing
但如果没有轻微的复杂性,您需要使用
访问它们names['spec_grp'][0]
names['spec_grp'][1]
如果我正确地阅读你的意图,上面的代码可以将这些值与选项标志组合起来,以便
options['spec_grp'] = (fname_for_spec_grp, sname_for_spec_group)
if options['spec_grp']:
assign_all_special_groups(apps, options["spec_grp"][0], options["spec_grp"][1])
这使初始化没有None
值的配置元素变得很重要,但这也是一种很好的做法。
但是我没有让你的通话代码更长更难读?均田。是否为一些额外角色为您带来了灵活性,可维护性和安全性?是的。它确实将三个数据结构(选项,fnames,snames)转换为一个字典,表示是否需要一个选项,如果需要,它的参数是什么。
答案 1 :(得分:1)
您只需创建一个包含属性 PhoneValue=0
if (condition== "new"):
PhoneValue=int(PhoneValue+10)
else:
PhoneValue=int(PhoneValue+9)
if GPS==bool(input("true")):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
if WiFi==eval(bool(input("true"))):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
if camera==eval(bool(input("true"))):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
global PhoneValue
的类ReadersManager
,制作该类的函数方法并访问其中的flags
。
答案 2 :(得分:1)
最好的方法是看看其他人是如何做到的,在这种情况下是ConfigParser standard module。这使用字典来存储和检索配置数据(实际上它使用字典的字典,但我们不需要)。关键是字典可以将名称与大多数内容相关联,使用数据来描述数据的位置远比硬编码更好。
在您的情况下,字典
options = {
'USE_SPEC_GROUP': False,
'USE_PREF': False,
}
但它是一本字典,所以我可以根据需要添加它
options['available'] = False
甚至可以轻松进行批量初始化:
options = {}
for option in "car plane train boat".split():
options[option] = False
当然在条件中访问它们很容易
if options['boat']:
# do boat things
现在你有一个传递包含所有配置数据的变量:
some_function(options)
当像dict
这样的基本类型本身非常有用时,无需使用类。