'Calling python class method which has no argument

I am new to python (coming from the c++ world) and was experimenting with class methods. I created a method without any argument (purposefully avoided self argument in this case). Then I tried to call it

class car:

    def car_method():
        print("Inside Car method")


obj = car_method()
obj.car_method()    <---- this creates error: TypeError: car_method() takes 0 positional arguments but 1 was given

I think this error is because, In Python, every class method, when called is always passed at least one argument which is that object's reference. am I correct?

Then to experiment further, I wrote

obj.car_method      <----- assuming I am not passing any argument to it

but the function printed nothing.

Then I tried to print the type of it using

print(obj.car_method)

which resulted in

bound method car.car_method of <__main__.car object at 0x005D2290>

Can anyone explain what is going on here? How do I 'call' the car_method? If there is no way to call the car_method, why does python let me define the method without any argument?

I am trying to get a good grasp on the basics here. Can I even call car_method as a class method? or it is just a method defined inside a class?



Solution 1:[1]

In Python, all the methods of the class receive an instance of the class object implicitly as the first argument.

It's general practice in Python to name the first argument in class methods as self it's like this in C and Java-like languages. The only difference, it's not a reserved keyword and you can name it anything. Though it's a general convention to use self as it is more readable to Python programmers and Python documentation, IDE parsers. Read the docs.

You can access class methods and variables across methods of the class using self. A very simple example showing the use case of self:

In [37]: class car:
    ...:     def __init__(self):
    ...:         self.car_name = 'Jaguar'
    ...:
    ...:     def car_method(self):
    ...:         print("I can access " + self.car_name + " because I have
    ...: self")
    ...:         print("Inside Car method")
    ...:
    ...:     def another_method(self):
    ...:         # this calls car_method
    ...:         self.car_method()
    ...:

In [38]: c = car()

In [39]: c.another_method()
I can access Jaguar because I have self
Inside Car method

If you want a classmethod. You can define a class method in Python as:

class car:

    @classmethod
    def car_method(cls):
        print("Inside Car method")

The little thing @classmethod on top of the car_method method is called decorator in Python. But even in class methods, the class instance is passed as an argument in car_method.

If you want to call your method car_method without an argument and do not need to access class/instance variables(these are called static methods). You can define your method as a static method with a @staticmethod decorator.

class car:

    @staticmethod
    def car_method():
        print("Inside Car method")

Here no self is passed as argument and you can call car_method as car().car_method()

Why Python allow car_method to be created even when self is passed as an argument?

It's because Python is not statically typed like C. It's a dynamic language. Unlike statically-typed languages, all the type, function argument, etc checking happens at runtime in Python

To know more about @classmethod and @staticmethod decorator, read about @classmethod and @staticmethod in this awesome SO thread

Solution 2:[2]

in python a method of class is defined by like this:

class MyObj(object):

    def my_method(self):
        pass

always at least one first argument which is the instance itself.

Solution 3:[3]

To access ca_method() inside car class, you just need to create an instance of the car class and then use the method. For example:

class car:

    def car_method():
       print("Inside Car method")

a = car()
a.car_method()

or just simply:

class car:
    
    def car_method():
           print("Inside Car method")
    
car().car_method()

Solution 4:[4]

TESTED Add "self" argument.

class car:
      def car_method(self):
         print("Inside Car Method") 
obj=car() 
obj.car_method()

I had the same challenge but adding the self resolved it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Yun Luo
Solution 3 Nitish
Solution 4