Why do I get "TypeError: Missing 1 required positional argument: 'self'"?
- 2024-11-22 08:47:00
- admin 原创
- 221
问题描述:
I have some code like:
class Pump:
def __init__(self):
print("init")
def getPumps(self):
pass
p = Pump.getPumps()
print(p)
But I get an error like:
Traceback (most recent call last):
File "C:UsersDomDesktop est est.py", line 7, in <module>
p = Pump.getPumps()
TypeError: getPumps() missing 1 required positional argument: 'self'
Why doesn't __init__
seem to be called, and what does this exception mean? My understanding is that self
is passed to the constructor and methods automatically. What am I doing wrong here?
See Why do I get 'takes exactly 1 argument (2 given)' when trying to call a method? for the opposite problem.
解决方案 1:
To use the class, first create an instance, like so:
p = Pump()
p.getPumps()
A full example:
>>> class TestClass:
... def __init__(self):
... print("init")
... def testFunc(self):
... print("Test Func")
...
>>> testInstance = TestClass()
init
>>> testInstance.testFunc()
Test Func
解决方案 2:
You need to initialize it first:
p = Pump().getPumps()
解决方案 3:
Adding a @classmethod
decorator to the method allows for calling it like Pump.getPumps()
.
A class method receives the class as the implicit first argument, just like an instance method receives the instance.
class Pump:
def __init__(self):
print("init")
@classmethod
def getPumps(cls):
pass
解决方案 4:
The self
keyword in Python is analogous to this
keyword in C++ / Java / C#.
In Python 2 it is done implicitly by the compiler (yes Python does compilation internally).
It's just that in Python 3 you need to mention it explicitly in the constructor and member functions. example:
class Pump():
# member variable
# account_holder
# balance_amount
# constructor
def __init__(self,ah,bal):
self.account_holder = ah
self.balance_amount = bal
def getPumps(self):
print("The details of your account are:"+self.account_number + self.balance_amount)
# object = class(*passing values to constructor*)
p = Pump("Tahir",12000)
p.getPumps()
解决方案 5:
You can also get this error by prematurely taking PyCharm's advice to annotate a method @staticmethod. Remove the annotation.
解决方案 6:
Remember 2 points
While defining the class do not enclose the class name by () bracket.
class Pump:
def __init__(self):
Also while instantiating class by object do not forget to use () bracket. Because only then above error is displayed.
If you want to call method without instantiating the object then inline instantiating
Pump().getPumps()
But ideally best practice is to instantiate the object with short key and then use that object instantiated to call the methods of the class, like
p = Pump()
p.getPumps()
解决方案 7:
If skipping parentheses for the object declaration (typo), then exactly this error occurs.
# WRONG! will result in TypeError: getPumps() missing 1 required positional argument: 'self'
p = Pump
p.getPumps()
Do not forget the parentheses for the Pump object
# CORRECT!
p = Pump()
p.getPumps()
解决方案 8:
I got the same error below:
TypeError: test() missing 1 required positional argument: 'self'
When an instance method had self
, then I called it directly by class name as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
Person.test() # Here
And, when a static method had self
, then I called it by object or directly by class name as shown below:
class Person:
@staticmethod
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
So, I called the instance method with object as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
And, I removed self
from the static method as shown below:
class Person:
@staticmethod
def test(): # <- "self" removed
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
Then, the error was solved:
Test
In detail, I explain about instance method in my answer for What is an "instance method" in Python? and also explain about @staticmethod and @classmethod in my answer for @classmethod vs @staticmethod in Python.
解决方案 9:
This error may also be raised if a required positional argument for a function is not passed. For example the following triggers the error.
def func(value, *args, **kwargs):
pass
func() # <--- TypeError: func() missing 1 required positional argument: 'value'
func(a=1, b=2) # <--- TypeError: func() missing 1 required positional argument: 'value'
# passing the required arg solves the issue
func(30) # <--- OK
func(3, a=1, b=2) # <--- OK
The above example is very simple but if func()
was imported from a module, it would be less obvious. For example, numpy module's allclose
function (which checks if two arrays are close enough) expects two positional arguments. If you pass the two arrays as a tuple/list, you'll get the TypeError in the title.
import numpy as np
np.allclose(([1, 2], [1, 1])) # <--- TypeError
np.allclose([1, 2], [1, 1]) # <--- OK
解决方案 10:
BEFORE
class Person:
def __init__(self, full_name, uuid, user_type, working_hours=None):
self.full_name = full_name
self.uuid = uuid
def load_data(filename):
print("Data")
def load_readers(self):
return self.load_data("readers.txt")
AFTER
class Person:
def __init__(self, full_name, uuid, user_type):
self.full_name = full_name
self.uuid = uuid
self.user_type = user_type
def load_data(self, filename):
print("Data")
def load_readers(self):
return self.load_data("readers.txt")
In my situation, the error was caused by a missing self keyword in the load_data()
function, which was used in the load_readers()
function.
Try to check if all your functions have the self
keyword
HOW I CALLED THE CLASS
if __name__ == '__main__':
person = Person("Foo", 1222, "READER")
print(person.load_readers())
So instead of using the class name, first initiate the class object to call the function.
扫码咨询,免费领取项目管理大礼包!