Estimated reading time: 2 minutes
So you may be using Python Classes and have encountered the problem TypeError: First Argument Must be Callable. So what does the problem mean and how can you fix it?
In this article, we are looking to explain how it may occur and the easy fix you can apply to stop the problem in the future.
Let us understand calling Functions/Methods first
Normally in a computer python program, you will need to use a function/method as it has the functionality that will save you time, and can continuously be reused.
A classic example is print(“Hello”) which handles all the required logic to show this on a screen. Its output is quickly viewable, and there is not any need to understand what is going on in the background.
Here in this example, we have run the function on its own, as a result, it does not need to point to somewhere else to run the logic it contains.
The error we are looking to resolve is part of the problem. A function/method can be run on its own, or from within a Class.
The defining difference is that on its own it needs the parenthesis i.e. (), but if you call it from within a class, then it has to be handled differently.
Seeing the Type Error First Argument must be callable and fixing it
In the below, we have a block of code, that produces the error we are trying to fix.
Following on from what was discussed above, the offending line is highlighted.
In particular, the problem lies with printprogress() . This is been called, but in actual fact, the problem is that when you have the logic written like this, it gives the error this blog post was set up for.
In essence, it is trying to run the program from that exact point, which python does not allow.
Removing the parenthesis then allows the program to go and find the module it is referencing and then run the logic contained within that:
import schedule
import time
class scheduleprint():
def printprogress(self):
print("Start of Processing")
print("Processing Complete")
def schedule_a_print_job(self, type="Secs", interval=5):
if type == "Secs": # Fed from the function paramaters
schedule.every(interval).seconds.do(self.printprogress())===> The problem is here, remove the () after printprogress.
# Including the parentheses after printprogess will throw an error as you cant run that method directly from there you can only call it.
if type == "Mins": # Fed from the function paramaters
schedule.every(interval).minutes.do(self.printprogress)
# Including the parentheses after printprogess will throw an error as you cant run that method directly from there you can only call it.
while True:
schedule.run_pending()
time.sleep(1) # The number of seconds the Python program should pause execution.
run = scheduleprint() # initiating an instance of the class "scheduleprint"
run.schedule_a_print_job() # running the function contained within the class.
In summary to help troubleshoot this problem:
(A) Check your code to see where it is calling a module within a class.
(B) Next make sure that in that call no parenthesis are present, otherwise it wont be able to find the module.