简体   繁体   English

python 过滤器 function 与 arguments

[英]python filter function with arguments

Lets say I've a list of ScriptMetadata object假设我有一个 ScriptMetadata object 列表

class ScriptMetadata:
  id = 1
  script_name = "test"
  script_run_start_time = 1
  script_run_end_time = 3
  ..
  ..

I want to provide an API like below我想提供如下 API

class ScriptInfoParser:
    def get_filtered_data(filter_func):
      [I've logic here to obtain a uber list of ScriptMetadata]
      # apply the user supplied filter func on this uber list and return result
      result = filter(filter_func, all_metadata_list)
      return list(result)

If I want to provide a filter func such that give me the ScriptMetadata objects for which script_name is "foo" I can have如果我想提供一个过滤器函数,以便为我提供 script_name 为“foo”的 ScriptMetadata 对象,我可以拥有

    def get_foo_runs(script_metadata):
        if script_metadata.script_name == "foo":
            return script_metadata
print(ScriptInfoParser.get_filtered_data(get_foo_runs))

Question is how can I parameterize the filter func so that I can have one function that can take parameters dynamically and apply filtering问题是如何参数化过滤器功能,以便我可以拥有一个可以动态获取参数并应用过滤的 function

get_script_runs(script_name):
  <?? magic filter func>
  return ScriptInfoParser.get_filtered_data(magic_filter_func) # returns scriptmetadata list that matches script_name

Also I wanna go complicated ie more than one param eg give me scriptmetadata items for script_name="foo" and script_run_end_time < 2 etc etc我也想要 go 复杂,即不止一个参数,例如给我 script_name="foo" 和 script_run_end_time < 2 等的脚本元数据项

Any help appreciated任何帮助表示赞赏

This is very open ended question, and there are many ways of accomplishing this.这是一个非常开放的问题,有很多方法可以做到这一点。 One of the most readable ways to filter on various attributes might be to pass lambdas into a combining function.过滤各种属性的最易读的方法之一可能是将 lambdas 传递给组合 function。

filter_funcs = [
lambda script_metadata: script_metadata.script_name == "foo",
lambda script_metadata: script_metadata.script_run_end_time < 2
]
def apply_filters(script_metadata, filter_funcs):
    for filter_func in filter_funcs:
        if not filter_func(script_metadata):
            return False
    return True

You could also keep the inputs shorter by using eval.您还可以使用 eval 使输入更短。

filter_strs = [
"script_name == 'foo'",
"script_run_end_time < 2",
]
def apply_filters(script_metadata, *args):
    for filter_str in args:
        if not eval(f"script_metadata.{filter_str}"):
            return False
    return True

apply_filters(script_metadata,
              "script_name =='foo'",
              "script_run_end_time < 2")
apply_filters(script_metadata, *filter_strs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM