Reputation: 4352
I want to design a python decorator
that takes a function which is decorated and passes it down to another function. Here is code explanation of what I am trying to do:
def run_decorator(run_batch):
# inner function can access the outer local
# functions like in this case "func"
def check(command_to_run):
@functools.wraps(command_to_run)
def wrapper(*args, **kwargs):
batch_json_path = kwargs['batch_json_path']
batch_name = kwargs['batch_name']
folder_path = kwargs['folder_path']
if batch_json_path is not None:
if batch_present(batch_json_path, batch_name):
run_batch(batch_json_path, command_to_run, batch_name)
return wrapper
return check
def run_batch(batch_abs_path, command_to_run, batch_name=None):
with open(batch_abs_path) as json_file:
variant = ...
tag_data = ...
command_to_run(variant, batch_name, tag_data)
@run_decorator(run_batch=run_batch)
def load_tag_for_variant(variant, batch_name, tag_data):
Is such behavior possible to achieve? Any suggestions would be greatly appreciated.
Upvotes: 2
Views: 224
Reputation: 1965
You indicated in a comment: I need to pass to the decorator 3 parameters: batch_json_path, batch_name and folder_path which are not the parameters of the load_tag_for_variant function, but should somehow be fed into the decorator / load_tag_for_variant at the moment program runs.
.
I understand from that, that you want to pass in those arguments at decoration time. To do this you should pass them to the run_decorator
function.
def run_decorator(run_batch, batch_json_path, batch_name, folder_path):
def check(command_to_run):
@functools.wraps(command_to_run)
def wrapper(*args, **kwargs):
if batch_json_path is not None:
if batch_present(batch_json_path, batch_name):
run_batch(batch_json_path, batch_name, command_to_run, *args, **kwargs)
return wrapper
return check
@run_decorator(run_batch, batch_json_path="a_path", batch_name="a_name", folder_path="a_path")
def load_tag_for_variant(variant, batch_name, tag_data):
...
You also want to pass the args (variant, batch_name, tag_data
) and kwargs with which you call the decorated function on to the original function (load_tag_for_variant
/command_to_run
). With the example function you have this can be done like this:
def run_batch(batch_abs_path, batch_name, command_to_run, *args, **kwargs):
command_to_run(*args, **kwargs)
...
Given that you have batch_name
in there twice, I'm not sure whether you want this defined at decoration time or at function invocation. If you just want to get it from the kwargs for instance, you can do kwargs.get('batch_name')
.
Upvotes: 1