call functions based on dynamic list from the user

rkue9o1l  于 2022-09-18  发布在  Java
关注(0)|答案(6)|浏览(127)

bounty 5天后到期。这个问题的答案有资格获得+50的声誉奖励。Rahul Sharma正在寻找这个问题的最新答案

我在我的Django应用程序中有一个报告生成API,它接受报告的名称作为用户的输入,用户可以从下拉菜单中选择不同的报告

reports = request.GET['reports'].split(',')

示例:

print("selected reports", reports)

    >>seleceted reports ['AS', 'DD', 'IS', 'LM']

现在这个reports可以根据用户的不同而不同,我有一个字典,其中包含创建这些报告的所有功能

master = {
        'AS': Summary(df, description_dict, emp),
        'AH': lastSeenMissingAsset(df, emp, description_dict),
        'MS': missingScans(df, emp),
        'IS': individualScans(df),
        'LM': tagMismatch(df, emp),
        'MAS': missingAssets(df, emp, description_dict, deployed_df),
        'MAU': missingAudit(df, pd.to_datetime(tt).date()),
        'DD': dumpData(df)
          }                 ###this calls every report first

如何根据从User获得的动态列表调用字典中的函数?

我试过:

final={}
    print("selected reports", reports)
    for i in reports:
        final[i] = master[i]
    print("final", final)

这是可行的,但由于字典的原因,所有函数都是首先调用的,我如何才能只调用选定的报表?

30byixjq

30byixjq1#

我想我明白你想做什么了。您可以将主列表更改为函数字典,而不是如下所示的函数结果。我不能100%确定结尾的语法,但我知道这是可能的。

master = {
            'AS': audit_summary,
            'AH': audit_health,
            'MS': missing_scan,
            'IS': individual,
            'LM': loc_mis,
            'MAS': missing_assets,
            'DD' : dump,
              }

def callAllTheFuncts(data):
    for item in data:
        master[item]()
inb24sb2

inb24sb22#

我建议创建一本词典,这样它就可以分别包含可计算词和论元。这可以防止不想要的呼叫。以下是一个简化的示例,您可以根据需要进行修改:

data = {
    'a': {'function': print, 'parameters': ['a']},
    'b': {'function': print, 'parameters': ['b']},
    'c': {'function': print, 'parameters': ['c']}
}

def call_funcs():
    for _, v in data.items():
        v['function'](*v['parameters'])

call_funcs()

# Output:

# a

# b

# c

当然,您可以使用字典作为参数而不是列表,但请记住将*替换为**作为关键字参数。

使用您的参数,源词典将如下所示:

master = {
    'AS': {'function': Summary, 'parameters': [df, description_dict, emp]},
    'AH': {'function': lastSeenMissingAsset, 'parameters': [df, emp, description_dict]},
    'MS': {'function': missingScans, 'parameters': [df, emp]},
    'IS': {'function': individualScans, 'parameters': [df]},
    'LM': {'function': tagMismatch, 'parameters': [df, emp]},
    'MAS': {'function': missingAssets, 'parameters': [df, emp, description_dict, deployed_df]},
    'MAU': {'function': missingAudit, 'parameters': [df, pd.to_datetime(tt).date()]},
    'DD': {'function': dumpData, 'parameters': [df]}
}
7gcisfzg

7gcisfzg3#

for i in selected_reports:
    masters[i]   # this will call the function

假设变量selected_reports包含列表

wz3gfoph

wz3gfoph4#

在您的帖子中,我不清楚您是打算将报表内容硬编码到master中,还是只希望按需调用报表函数。您的代码对报告值进行了硬编码,但您编写的文本表明您希望按需调用这些函数。

按需更高效--假设每个用户/请求的内容不同,所以我假定采用这种方法。

但是,如果您打算只生成一次报告,而不是每次请求,那么解决方案将会改变。

您可以使用函数式工具.部分来创建一个可调用的对象,该对象调用您的报告生成函数。该函数允许创建“部分”函数/方法调用,稍后可以通过添加额外的argskwargs来调用这些调用(有时这很有用)。但它也可以用于创建调用时不需要额外参数的可调用对象。

摘自官方文件:
返回一个新的分部对象,当被调用时,它的行为将类似于使用位置参数args和关键字参数关键字调用的函数。如果向调用提供了更多参数,则会将它们附加到args。如果提供了其他关键字参数,它们将扩展和覆盖关键字。

from functools import partial

report_generators = dict(
    AS = partial(Summary, df, description_dict, emp),
    AH = partial(lastSeenMissingAsset, df, emp, description_dict),
    MS = partial(missingScans, df, emp),
    IS = partial(individualScans, df),
    LM = partial(tagMismatch, df, emp),
    MAS = partial(missingAssets, df, emp, description_dict, deployed_df),
    MAU = partial(missingAudit, df, partial(pd.to_datetime(tt).date, )),
    DD = partial(dumpData, df),
)

def my_route(self):
    report_ids = request.GET['reports'].split(',')
    # Generate as a flat list.
    report_contents = [report_generators[report_id]() for report_id in report_ids]
    # ..or generate as a dict, keyed by report id.
    report_contents = {report_id:report_generators[report_id]() for report_id in report_ids}
    # Now do stuff with the contents :)
dy1byipe

dy1byipe5#

正如所有评论中所述,问题在于您的所有功能(摘要等)在创建主词典时调用一次。然后迭代选定的报告,从而再次调用一些函数。

解决方案确实是修改master并使用Partial:

master = {
    'AS': partial(Summary, df, description_dict, emp),
    'AH': partial(lastSeenMissingAsset, df, emp, description_dict),
    'MS': partial(missingScans, df, emp),
    'IS': partial(individualScans, df),
    'LM': partial(tagMismatch, df, emp),
    'MAS': partial(missingAssets, df, emp, description_dict, deployed_df),
    'MAU': partial(missingAudit, df, pd.to_datetime(tt).date()),
    'DD': partial(dumpData, df)
}

然后,当您遍历Master时:

for i in reports:
    final[i] = master[i]()  # notice the () --> master[i] is a Callable
6ioyuze2

6ioyuze26#

您只需要将函数和相应的参数分开存储,因此只需在需要时连接并调用函数即可。

例如:

master = {
  'AS': (Summary, (df, description_dict, emp)),
  'AH': (lastSeenMissingAsset, (df, emp, description_dict)),
  'MS': (missingScans, (df, emp)),
  'IS': (individualScans, (df,)),
  'LM': (tagMismatch, (df, emp)),
  'MAS': (missingAssets, (df, emp, description_dict, deployed_df)),
  'MAU': (missingAudit, (df, pd.to_datetime(tt).date())),
  'DD': (dumpData, (df,))
}

final={}
print("selected reports", reports)
for i in reports:
  fn, args = master[i]
  final[i] = fn(*args)
print("final", final)

相关问题