I'm reading through the documentation for the schedule API and in the "Run in the Background" example they define the run method as a class method in their ScheduleThread class. The code is below:
import threading import time import schedule def run_continuously(interval=1): """Continuously run, while executing pending jobs at each elapsed time interval. @return cease_continuous_run: threading. Event which can be set to cease continuous run. Please note that it is *intended behavior that run_continuously() does not run missed jobs*. For example, if you've registered a job that should run every minute and you set a continuous run interval of one hour then your job won't be run 60 times at each interval but only once. """ cease_continuous_run = threading.Event() class ScheduleThread(threading.Thread): @classmethod def run(cls): while not cease_continuous_run.is_set(): schedule.run_pending() time.sleep(interval) continuous_thread = ScheduleThread() continuous_thread.start() return cease_continuous_run def background_job(): print('Hello from the background thread') schedule.every().second.do(background_job) # Start the background thread stop_run_continuously = run_continuously() # Do some other things... time.sleep(10) # Stop the background thread stop_run_continuously.set() I don't understand why they use @classmethod here. From doing a bit of research it seems that run() should always be an instance method in Thread subclasses. Is this a mistake or am I missing something?
I ran the code unaltered from the documentation and then I changed the classmethod to an instance method (removed the decorator and replaced run(cls) with run(self)) and ran the code again and the behavior was identical.
I expected something to break or there to be different behavior.
classmethodcan be called on an instance, just like a regular instance method can be, it will just be passed the class rather than the instance it was called on as the first argument. Since the example'srunmethod doesn't use eitherselforcls, it doesn't really matter which it gets. As you say, there's no real reason for it to be aclassmethod, but it still works.runcould also be astaticmethod, right? Since the instance and the class aren't used? I'm assuming again that there is no real reason to usestaticmethodhere over the others and the best solution is to restructure as in your answer below.selfinside of it and followed it blindly.