431

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:\Users\Dom\Desktop\test\test.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?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
DominicM
  • 6,520
  • 13
  • 39
  • 60

9 Answers9

569

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
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
98

You need to initialize it first:

p = Pump().getPumps()
JBernardo
  • 32,262
  • 10
  • 90
  • 115
20

Works and is simpler than every other solution I see here :

Pump().getPumps()

This is great if you don't need to reuse a class instance. Tested on Python 3.7.3.

Eli O.
  • 1,543
  • 3
  • 18
  • 27
  • 5
    This is practically a duplicate of [JBernardo's answer](https://stackoverflow.com/a/17534365/4518341). Note that he also doesn't save the instance, unless `getPumps()` returns `self`, which would be bizarre. – wjandrea Dec 31 '20 at 04:18
10

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
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Atom
  • 320
  • 1
  • 6
  • 14
7

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()
Ghost Ops
  • 1,710
  • 2
  • 13
  • 23
Tahir77667
  • 2,290
  • 20
  • 16
  • 3
    It's not a keyword, just a convention. – wjandrea Jul 30 '20 at 19:17
  • 4
    What do you mean by *"In Python 2 it is done implicitly by the compiler"*? AFAIK Python 2 never set `self` implicitly. – wjandrea Jul 30 '20 at 19:17
  • This is not valid Python code. What are you trying to demonstrate exactly? To start, Python comments use `#`, not `//`; you don't need to declare member attributes at the class-level; and those pipes seem to be out-of-place. – wjandrea Dec 31 '20 at 04:16
  • 2
    *"In Python 2 it is done implicitly by the compiler"* citation needed. – Sören Apr 22 '22 at 20:55
  • 1
    There are many differences between Python 2.x and Python 3.x, even some that concern how classes work. This, however, is absolutely not one of them. Aside from that, the problem was **nothing to do with** explicit `self`. The problem is simply about **instantiating the class**. – Karl Knechtel Feb 18 '23 at 20:16
5

You can also get this error by prematurely taking PyCharm's advice to annotate a method @staticmethod. Remove the annotation.

gherson
  • 169
  • 2
  • 9
  • Another possibility in the neighborhood of this answer is if you declare a method as an `@staticmethod` and then include (or retain) `self` as the first positional argument.. – DaveL17 May 03 '23 at 01:04
1

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.

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
1

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()
Daniel Nelson
  • 1,968
  • 1
  • 12
  • 11
  • See also: [What does it mean when the parentheses are omitted from a function or method call?](https://stackoverflow.com/questions/21785933). – Karl Knechtel Feb 18 '23 at 20:23
0

Remember 2 points

  1. While defining the class do not enclose the class name by () bracket.

    class Pump:    
    def __init__(self):
    
  2. 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()