简体   繁体   English

当我调用内部/装饰函数时,我可以将参数传递给我的装饰器函数吗?

[英]Can I pass an argument into my decorator function when I call the inner/decorated function?

Hopefully that terminology is correct.希望这个术语是正确的。 I have this decorator function, which reads a text file:我有这个装饰器函数,它读取一个文本文件:

def read_commands(inner, path=BATCH_PATH):
    with open(path) as f:
        commands = ['python ' + line.replace('\n', '') for line in f]

    def wrapper(*args, **kwargs):
        for command in commands:
            inner(command, *args, **kwargs)

    return wrapper

And here's one of the functions it decorates:这是它装饰的功能之一:

@read_commands
def execute_multi_commands(command, count):
    LOG.info(f'Executing command {count}: {command}')
    os.system(command)
    count += 1

I want to be able to change path from default when I call execute_multi_commands , like so in my main :我希望能够在调用execute_multi_commands时更改默认路径,就像在我的main

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('-b', '--batch', action='store', type=str, dest='batch')
    args = parser.parse_args()
    
    count = 1
    execute_multi_commands(count, path=args.batch)

However, obviously this does not work as path is not an argument in execute_multi_commands .但是,显然这不起作用,因为path不是execute_multi_commands的参数。 Is it possible for me to pass path to the decorator function read_commands , when I call execute_multi_commands ?当我调用execute_multi_commands时,是否可以将path传递给装饰器函数read_commands - or, more likely, any functionally equivalent alternatives? - 或者,更可能的是,任何功能等效的替代品?

You cannot, at least the way your decorator is written.你不能,至少你的装饰器是这样写的。 When you decorate a function, it's similar to doing:当你装饰一个函数时,它类似于做:

def execute_multi_commands(command, count):
    LOG.info(f'Executing command {count}: {command}')
    os.system(command)
    count += 1

execute_multi_commands = read_commands(execute_multi_commands)

So after this point, read_commands has already been executed, and the file has been read.所以在这之后, read_commands已经被执行了,文件也被读取了。

What you can do is change the decorator to read the file in the wrapper, something like:您可以做的是更改装饰器以读取包装器中的文件,例如:

def read_commands(inner, path=BATCH_PATH):

    def wrapper(*args, **kwargs):

        if "path" in kwargs:
            path_ = kwargs.pop("path")
        else:
            path_ = path

        with open(path_) as f:
            commands = ['python ' + line.replace('\n', '') for line in f]

        for command in commands:
            inner(command, *args, **kwargs)

    return wrapper

...but this means reading the file every time you call the decorated function, which is slightly different than what you were doing before. ...但这意味着每次调用装饰函数时都会读取文件,这与您之前所做的略有不同。

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

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