This question already has answers here:
"TypeError: method() takes 1 positional argument but 2 were given" but I only passed one
(10 answers)
Closed 6 months ago.
I am new to Python and I have written this simple script:
#!/usr/bin/python3
import sys
class Hello:
def printHello():
print('Hello!')
def main():
helloObject = Hello()
helloObject.printHello() # Here is the error
if __name__ == '__main__':
main()
When I run it (./hello.py) I get the following error message:
Traceback (most recent call last):
File "./hello.py", line 13, in <module>
main()
File "./hello.py", line 10, in main
helloObject.printHello()
TypeError: printHello() takes no arguments (1 given)
Why does Python think I gave printHello() an argument while I clearly did not? What have I done wrong?
The error is referring to the implicit self argument that is passed implicitly when calling a method like helloObject.printHello(). This parameter needs to be included explicitly in the definition of an instance method. It should look like this:
class Hello:
def printHello(self):
print('Hello!')
If you want printHello as instance method, it should receive self as argument always(ant python will pass implicitly) Unless you want printHello as a static method, then you'll have to use #staticmethod
#!/usr/bin/python3
import sys
class Hello:
def printHello(self):
print('Hello!')
def main():
helloObject = Hello()
helloObject.printHello() # Here is the error
if __name__ == '__main__':
main()
As '#staticmethod'
#!/usr/bin/python3
import sys
class Hello:
#staticmethod
def printHello():
print('Hello!')
def main():
Hello.printHello() # Here is the error
if __name__ == '__main__':
main()
Calling a method on the instance of an object returns the object itself (usually self) to the object. For example, calling Hello().printHello() is the same as calling Hello.printHello(Hello()), which uses an instance of a Hello object as the first argument.
Instead, define your printHello statement as def printHello(self):
Related
This question already has answers here:
"TypeError: method() takes 1 positional argument but 2 were given" but I only passed one
(10 answers)
Closed 8 months ago.
I'm trying to implement a subclass and it throws the error:
TypeError: worker() takes 0 positional arguments but 1 was given
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker():
pass
def DownloadProc(self):
pass
Your worker method needs 'self' as a parameter, since it is a class method and not a function. Adding that should make it work fine.
If the method doesn't require self as an argument, you can use the #staticmethod decorator to avoid the error:
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
#staticmethod
def worker():
pass
def DownloadProc(self):
pass
See https://docs.python.org/3/library/functions.html#staticmethod
You forgot to add self as a parameter to the function worker() in the class KeyStatisticCollection.
This can be confusing especially when you are not passing any argument to the method. So what gives?
When you call a method on a class (such as work() in this case), Python automatically passes self as the first argument.
Lets read that one more time:
When you call a method on a class (such as work() in this case), Python automatically passes self as the first argument
So here Python is saying, hey I can see that work() takes 0 positional arguments (because you have nothing inside the parenthesis) but you know that the self argument is still being passed automatically when the method is called. So you better fix this and put that self keyword back in.
Adding self should resolve the problem. work(self)
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker(self):
pass
def DownloadProc(self):
pass
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker(self):
pass
def DownloadProc(self):
pass
I get this error whenever I mistakenly create a Python class using def instead of class:
def Foo():
def __init__(self, x):
self.x = x
# python thinks we're calling a function Foo which takes 0 args
a = Foo(x)
TypeError: Foo() takes 0 positional arguments but 1 was given
Oops!
Check if from method with name method_a() you call method with the same name method_a(with_params) causing recursion
just pass self keyword in def worker(): function
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker(self):
pass
def DownloadProc(self):
pass
another use case for this error is when you import functions within the class definition. this makes the subsequent function calls a part of the class object. In this case you can use #staticmethod on the library import function or make a static path call directly to the function. see example below
In this example "self.bar()" will throw a TypeError, but it can be fixed in two ways
# in lib.py
def bar():
print('something to do')
# in foo.py
class foo():
from .lib import bar
def __init__(self):
self.bar()
Option 1:
# in lib.py
def bar():
print('something to do')
# in foo.py
class foo():
from .lib import bar
def __init__(self):
lib.bar()
Option 2:
# in lib.py:
#staticmethod
def bar():
print('something to do')
# in foo.py
class foo():
from .lib import bar
def __init__(self):
self.bar()
When doing Flask Basic auth I got this error and then I realized I had wrapped_view(**kwargs) and it worked after changing it to wrapped_view(*args, **kwargs).
class KeyStatisticCollection():
def GenerateAddressStrings(self):
pass
def worker():
return blabla
def DownloadProc(self):
abc = self.GenerateAddressStrings()
#abc = GenerateAddressStrings()#error
blabla = worker()
#blabla = self.worker()#error
i think this is a better explaination about using self param
I'm trying to connect to a sqllite database using:
class Sqllite_utilities(object):
def __init__(self):
parser = argparse.ArgumentParser()
parser.add_argument("-s","--source", type=str,
help="source table from db")
args = parser.parse_args()
print(args)
source_table= args.source
db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db"
dataset_db = dataset.connect(db_path)
self.dataset_table = dataset_db[source_table]
def missing_ids(self):
for user in self.dataset_table:
print(user['id'])
if __name__ == '__main__':
Sqllite_utilities.missing_ids(sys.argv[1])
When I do:
$ python find_missing_records.py -s test
I get:
Traceback (most recent call last):
File "find_missing_records.py", line 41, in <module>
Sqllite_utilities.missing_ids(sys.argv[1])
TypeError: unbound method missing_ids() must be called with Sqllite_utilities instance as first argument (got str instance instead)
(contact2E)
What am I doing wrong?
When doing:
Sqllite_utilities.missing_ids(sys.argv[1])
you're calling the missing_ids instance method with sys.argv[1] (a string) as self (functional way to call instance methods, but with the wrong object), which explains the error message.
It's clear that you have to create an instance of your object before being able to use the instance methods (the ones without #staticmethod or #classmethod decorators):
if __name__ == '__main__':
s = Sqllite_utilities()
the constructor parses the arguments, using argparse.ArgumentParser which uses sys.argv by default, so leave that aside, it'll work.
Then call your method on the instance:
s.missing_ids()
s is implicitly passed as self when calling missing_ids
As suggested from the top answer to this question: unbound method f() must be called with fibo_ instance as first argument (got classobj instance instead)
Add to your code:
if __name__ == '__main__':
obj = Sqllite_utilities()
s.missing_ids()
This question already has answers here:
How can I call a function within a class?
(2 answers)
Closed 6 years ago.
I am new in programming and I have faced a problem for which I can't find an answer... So here it is:
`class MyClass:
def printsmth():
print("Hello")
def main():
printsmth()
if __name__ == '__main__':main()`
I get an error which says :
Traceback (most recent call last):
File "untitled.py", line 1, in <module>
class MyClass:
File "untitled.py", line 6, in MyClass
if __name__ == '__main__':main()
File "untitled.py", line 5, in main
printsmth()
NameError: name 'printsmth' is not defined
Code included is just an example, but it is the same error that I get on my real code, if for example I would transfer my code from main() to if name == 'main' than it works perfectly. The thing is that I want to relaunch main() method in some parts of the code but I haven't even gone to that because I can't think of a solution to this error:/ Can you help me?
P.S I tried to move main() and if name == 'main' from MyClass and it didn't worked.
You are forgetting to pass self as the first parameter of your methods. Once you do this, you can callself.printsmth() as a method. Right now it's confused because you're calling it as a function rather than a method.
class MyClass:
def printsmth(self):
print("Hello")
def main(self):
self.printsmth()
I am trying to learn python i tried to import a class in another class but it is not working
Application.py:
class Application:
def example(self):
return "i am from Application class"
Main.py
class Main:
def main():
application = Application()
application.example()
if __name__ == "__main__":
Main.main()
This gives me :
File "Main.py", line 11, in <module>
Main.main()
TypeError: unbound method main() must be called with Main instance as first argument (got nothing instead)
The error has nothing to do with importing (Although you don't seem to import Application anywhere). The problem is that you use the main method like a static method without declaring it to be static.
To solve this, You either need to declare your main method as static or create an instance of the Main class.
As a static method (add the #staticmethod decorator):
class Main():
#staticmethod
def main():
...
With an Instance:
class Main():
def main(self):
....
if __name__ == "__main__":
myMain = Main() #create an instance
myMain.main() #call the function on the instance
Also, to import your Application class from Application.py, you would just write this:
from Application import Application
You should instantiate your Main class first.
if __name__ == '__main__':
myMain = Main()
myMain.main()
But this will give you another error:
TypeError: main() takes no arguments (1 given)
There are two ways to fix this. Either make Main.main take one argument:
class Main:
def main(self):
application = Application()
application.example()
or make Main.main a static method. In which case you don't have to instantiate your Main class:
class Main:
#staticmethod
def main():
application = Application()
application.example()
if __name__ == "__main__":
Main.main()
I have two files, one of the test.py is
import new.py
class Test:
def __init__(self):
return
def run(self):
return 1
if __name__ == "__main__":
one=Test()
one.run()
and new.py
class New:
def __init__(self):
one.run()
New()
Now when i run python test.py I get this error,
Traceback (most recent call last):
File "test.py", line 1, in <module>
import new.py
File "/home/phanindra/Desktop/new.py", line 5, in <module>
New()
File "/home/phanindra/Desktop/new.py", line 3, in __init__
one.run()
NameError: global name 'one' is not defined
But I want to use this instance of one in my New!!
Can I do this??
edit:
I want to access the variable in test.py in new.py to do some process and give them back to test.py. Isn't this possible?
If you want your New class to use the instance of Test you created, you have to pass it in as part of the constructor.
new.py
class New:
def __init__(self, one):
one.run()
test.py
import new
class Test:
def __init__(self):
return
def run(self):
return 1
if __name__ == "__main__":
one=Test()
two = new.New(one);
Playing around with globals is a great way to break your code without realizing how you did it. It is better to explicitly pass in the reference you want to use.
No, you can't. The closest you can get is to pass the thing you need in to the constructor:
class New(object):
def __init__(self, one):
one.run()
one is defined inside the if __name__=='__main__' block.
Consequently, one will get defined only if test.py is run as a script (rather than imported).
For the module new to access one from the test module, you'll need to pull one out of the if __name__ block:
test.py:
class Test:
def __init__(self):
return
def run(self):
return 1
one=Test()
if __name__ == "__main__":
one.run()
Then access one by the qualified name test.one:
new.py:
import test
class New:
def __init__(self):
test.one.run()
New()