简体   繁体   English

Python - 将函数传递给另一个 function 可以修改 arguments

[英]Python - Passing functions to another function where the arguments may be modified

I've written what's effectively a parser for a large amount of sequential data chunks, and I need to write a number of functions to analyze the data chunks in various ways.我已经为大量顺序数据块编写了有效的解析器,并且我需要编写许多函数来以各种方式分析数据块。 The parser contains some useful functionality for me such as frequency of reading data into (previously-instantiated) objects, conditional filtering of the data, and when to stop reading the file.解析器包含一些对我有用的功能,例如将数据读入(先前实例化的)对象的频率、数据的条件过滤以及何时停止读取文件。

I would like to write external analysis functions in separate modules, import the parser, and pass the analysis function into the parser to evaluate at the end of every data chunk read.我想在单独的模块中编写外部分析函数,导入解析器,并将分析 function 传递到解析器中,以便在每个数据块读取结束时进行评估。 In general, the analysis functions will require variables modified within the parser itself (ie the data chunk that was read), but it may need additional parameters from the module where it's defined.通常,分析函数需要在解析器本身内修改变量(即读取的数据块),但它可能需要来自定义它的模块的附加参数。

Here's essentially what I would like to do for the parser:这基本上是我想为解析器做的事情:

def parse_chunk(dat_file, dat_obj1, dat_obj2, parse_arg1=None, fun=None, **fargs):
    # Process optional arguments to parser...

    with open(dat_file,'r') as dat:
        # Parse chunk of dat_file based on parse_arg1 and store data in dat_obj1, dat_obj2, etc.
        dat_obj1.attr = parsed_data

        local_var1 = dat_obj1.some_method()

        # Call analysis function passed to parser
        if fun != None:
            return fun(**fargs)       

In another module, I would have something like:在另一个模块中,我会有类似的东西:

from parsemod import parse_chunk

def main_script():
    # Preprocess data from other files
    dat_obj1 = ...
    dat_obj2 = ...

    script_var1 = ...
    # Parse data and analyze
    result = parse_chunk(dat_file, dat_obj1, dat_obj2, fun=eval_prop,
                         dat_obj1=None, local_var1=None, foo=script_var1)
    
def eval_data(dat_obj1, local_var1, foo):
    # Analyze data
    ...
    return result

I've looked at similar questions such as this and this , but the issue here is that eval_data() has arguments which are modified or set in parse() , and since **fargs provides a dictionary, the variable names themselves are not in the namespace for parse() , so they aren't modified prior to calling eval_data() .我看过类似的问题,例如thisthis ,但这里的问题是eval_data()有 arguments ,它们在parse()中被修改或设置,并且由于**fargs提供了字典,因此变量名本身不在parse()的命名空间,因此在调用eval_data()之前它们不会被修改。

I've thought about modifying the parser to just return all variables after every chunk read and call eval_data() from main_script() , but there are too many different possible variables needed for the different eval_data() functional forms, so this gets very clunky.我考虑过修改解析器以在每次读取块后返回所有变量并从main_script()调用eval_data() ) ,但是不同的eval_data()功能 forms 需要太多不同的可能变量,所以这变得非常笨拙.

Here's another simplified example that's even more general:这是另一个更通用的简化示例:

def my_eval(fun, **kwargs):
    x = 6
    z = 1
    return fun(**kwargs)

def my_fun(x, y, z):
    return x + y + z

my_eval(my_fun, x=3, y=5, z=None)

I would like the result of my_eval() to be 12, as x gets overwritten from 3 to 6 and z gets set to 1. I looked into functools.partial but it didn't seem to work either.我希望my_eval()的结果为 12,因为 x 被从 3 覆盖到 6 并且 z 被设置为 1。我查看了functools.partial但它似乎也没有工作。

To override kwargs you need to do要覆盖你需要做的kwargs

kwargs['variable'] = value  # instead of just variable = value

in your case, in my_eval you need to do在你的情况下,在my_eval你需要做

kwargs['x'] = 6
kwargs['z'] = 1

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

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