2

I am directly calling a method on a class like this:

MyClass.action("Hello World!")

and inside the called method I need to refer to another method:

class MyClass:
    def action(data):
        print('first')
        # vvv How to perform this call?
        next_action(data)

    def next_action(data):
        print('second', data)

Usually, I would use self to access the method and attributes but by calling the method on the class there is no instance that self could refer to. How can I still access one method from another in this case?

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
Mick
  • 1,401
  • 4
  • 23
  • 40
  • 1
    "I tried using self to call next_action but I'm not sure how to obtain it at this point?" You would "obtain" it from the parameters - to write the methods properly, it should be included in the the parameters. Please keep in mind that `self` is **not a keyword** and **not in any way magical** - it is **just** a conventional name for the object upon which the method was called. The magic of method calls is implemented by the attribute lookup process. (As asked, the question is material that should be covered by any proper Python tutorial.) – Karl Knechtel May 10 '22 at 15:18
  • I know you've already received multiple answers, but I think it would be beneficial for you to read a tutorial on OOP :) https://docs.python.org/3/tutorial/classes.html – vaultah May 10 '22 at 15:25
  • I updated the question to explain why I was confused. I though that the class had been instantiated but it hadn't. – Mick May 10 '22 at 15:47
  • 2
    @Mick the confusion in this thread is because `myclass` is not the same as `MyClass`. If `myclass.action()` points to the class it should be `MyClass.action()`. It would help future readers to change one of these so they match. – Mark May 10 '22 at 15:53
  • It seems as if you are *generally* confused about the purpose of classes, and how to use them. My strong advice is to work through a tutorial. – Karl Knechtel May 10 '22 at 16:11
  • Nope. I understand OO. The way that MyClass is used is the confusing bit. It was using a path and get_class_name (not my code). I didn't realise that the method was called on the class and not an instance. – Mick May 10 '22 at 16:21

6 Answers6

4

Based on how you are calling it, it look like you are trying to define class methods. To do that include @classmethod decorator. It will then pass the class as the first argument, which you can use to call it.

class MyClass:
    @classmethod
    def action(cls, data):
        print('first')

        cls.next_action(data)

    @classmethod
    def next_action(cls, data):
        print('second', data)

MyClass.action('Hello World!')

If, in fact, you are actually trying to make instance methods, then you need to call them from an instance. In that case you define the class without the classmethod decorator and call it from an instance. Python will then pass a reference to the instance as the first argument. But you need to create the instance to call it:

class MyClass:
    def action(self, data):
        print('first')

        self.next_action(data)

    def next_action(self, data):
        print('second', data)

instance = MyClass()
instance.action('Hello World!')
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
Mark
  • 90,562
  • 7
  • 108
  • 148
  • 1
    Thanks, I don't want to change the way that it is called (someone elses code). So have added the @classmethod. – Mick May 10 '22 at 15:22
1

You need to write using the self argument.

class MyClass:
    def action(self, data):
        print('first')

        self.next_action(data)

    def next_action(self, data):
        print('second')
Albert Alonso
  • 656
  • 1
  • 6
  • 21
1

You need to create an instance (object) from your class and call it.

class MyClass:
    def action(self):
        print('first')

        self.next_action()

    def next_action(self):
        print('second')

my = MyClass()
my.action()

Then your methods always has self as a first argument which refers to object itself.

ex4
  • 2,289
  • 1
  • 14
  • 21
0

You have to put self as the first parameter of the method as such:

class MyClass:
    def action(self, data):
        print('first')

        self.next_action(data)

    def next_action(self, data):
        print('second')

And the name self is actually just a naming convention, so you can change it to whatever name you want it to be, it just has to be the first parameter. But of course I would advise you to stick with it.

CozyCode
  • 484
  • 4
  • 13
-1

Since these are member functions, call it as a member function on the instance, self.

def next_Action(self,data):
self.next_action(data)
user3369545
  • 310
  • 2
  • 14
-1

pass self that is the reference of the object

#!/usr/bin/env python3.10

class MyClass:
    def action(self, data):
        print('first')

        self.next_action(data)

    def next_action(self, data):
        print('second')

if __name__ == "__main__":
    myclass = MyClass()
    myclass.action('hmmm')

You can also make the methods as class methods by using @classmethod decorator if you don't want them to instance method

#!/usr/bin/env python3.10

class MyClass:

    @classmethod
    def action(cls, data):
        print('first')

        MyClass.next_action(data)

    @classmethod
    def next_action(cls, data):
        print('second')

if __name__ == "__main__":
    myclass = MyClass()
    myclass.action('hmmm')
Udesh
  • 2,415
  • 2
  • 22
  • 32