0

I'm trying to use a decorator for a function, while trying to pass a global variable to the decorator. However, I get an error message at the line with the decorator (@) stating that scheduler is not defined...

def wrap_task(scheduler_in):
    def inner(task):
        try:
            task()
        except:
            logger_sub.exception("Error!!!!")
            scheduler_in.shutdown(wait=False)
    return inner

@wrap_task(scheduler_in = scheduler)
def print_job():
    print("pipeline")
    raise FileExistsError

if __name__ == "__main__":
    scheduler = BlockingScheduler() # from APScheduler
    scheduler.add_job(print_job,'date',id="print_job")
    scheduler.add_listener(my_listener,EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
    (...) 

   

P.S.: The problem shouldn't be to use scheduler before it's defined, since I also create a listener for this scheduler and the listener itself uses the same shutdown command without any error.

An old man in the sea.
  • 1,169
  • 1
  • 13
  • 30
  • 1
    You should define `scheduler` before `print_job` – D Malan Feb 24 '22 at 08:48
  • well, you use a variable before you define it, that's the problem. you should also have a look at how to write paramterised decorators, your is... wrong. :) – timgeb Feb 24 '22 at 08:48
  • Wrap the task when you add it instead of using a decorator? `scheduler.add_job(wrap_task(scheduler_in=scheduler)(print_job),'date',id="print_job")` – Iain Shelvington Feb 24 '22 at 08:50
  • @DMalan If I do that, I get this message: «TypeError: func must be a callable or a textual reference to one» – An old man in the sea. Feb 24 '22 at 08:51
  • 1
    @timgeb could please be more precise in how it's wrong? How would I correct it? – An old man in the sea. Feb 24 '22 at 08:53
  • `wrap_task(scheduler_in = scheduler)` returns the function `inner`. `inner` is then applied to `print_job` like this: `print_job = inner(print_job)`. But now `print_job` isn't a function anymore, `inner` just executes `print_job` immediately and returns `None`. So now, `print_job = None` but you probably wanted a modified function `print_job`. – timgeb Feb 24 '22 at 08:55
  • @timgeb I don't see how what I've done is wrong, given what I see in this link in Example #1. https://www.geeksforgeeks.org/decorators-with-parameters-in-python/ – An old man in the sea. Feb 24 '22 at 08:59
  • @Anoldmaninthesea. This is the worst tutorial I have ever seen. example #1 is particularly bad. Try executing it. `my_func` runs immediately and after execution is set to `None`. print `my_func` and see for yourself. Their decorator made the function unusable. – timgeb Feb 24 '22 at 09:12
  • @timgeb how would you suggest to solve the issue, then? By the way, if you know of a better tutorial, I would be much obliged. – An old man in the sea. Feb 24 '22 at 09:16
  • 1
    @Anoldmaninthesea. forget that article and read [this](https://stackoverflow.com/questions/5929107/decorators-with-parameters) instead. – timgeb Feb 24 '22 at 09:17

0 Answers0