-1

Apologies if the following question has already been posed on StackOverflow, but I couldn't find it posted here, nor was I able to find an answer after some time spent Googling.

My question is as follows. I would expect the following Python code,

class MNL(object):

    def load_data():
        r = 3 + 4
        return r

    def load_data_wrapper():
        s = load_data()
        return s

to return the output "7". Instead I get the error message "NameError: name 'load_data' is not defined".

If I change the second-to-last line to "s = self.load_data()" I get "NameError: name 'self' is not defined". For reference, I'm using Python 3.6.5.

Any help would be very much appreciated!

user810643
  • 41
  • 5
  • You need to change it to `def load_data_wrapper(self):` before you can use `self.load_data()`. – Alasdair May 08 '19 at 22:45
  • Tried this already. I then get the error message " TypeError: load_data_wrapper() missing 1 required positional argument: 'self'" once I call "MNL.load_data_wrapper()" – user810643 May 08 '19 at 22:48

2 Answers2

2

Any reference to object methods or attributes in Python requires the self keyword, and it should always be the first parameter of any class method. To fix your code, it would be:

class MNL(object):

    def load_data(self):
        r = 3 + 4
        return r

    def load_data_wrapper(self):
        s = self.load_data()
        return s

The self parameter receives the reference of the object.

Lucas Abbade
  • 757
  • 9
  • 19
  • Cf. my comment above, executing this code and calling "MNL.load_data_wrapper()" I get the error message "TypeError: load_data_wrapper() missing 1 required positional argument: 'self'". Any idea why this is happening? – user810643 May 08 '19 at 22:52
  • Are you calling the function from a class object? You should have something like: `mnl = MNL()` `mnl.load_data_wrapper()` – Lucas Abbade May 08 '19 at 22:53
  • If you call `MNL.load_data_wrapper()` you are referencing the class itself, not an object of the class, firstly you need to instantiate an object of the class – Lucas Abbade May 08 '19 at 22:55
  • Indeed, calling "mnl = MNL().load_data_wrapper()" I get the desired output "7". That solved my problem, thanks for your help! – user810643 May 08 '19 at 23:02
  • You can also make the methods class methods or static methods. If you do so, instantiation is not needed. – iz_ May 08 '19 at 23:07
0

Based on the questions I see in the comments I wanted to offer up some changes to the code.

class MNL(object):
    @staticmethod
    def load_data():
        r = 3 + 4
        return r

    @classmethod
    def load_data_wrapper(cls):
        s = cls.load_data()
        return s

    def load_data_wrapper2():
        return MNL.load_data()

This utilizes Class and Static methods These do not operate on "self" but are methods that you still want to tie to a singular class

>>> MNL.load_data_wrapper2()
7
>>> MNL.load_data_wrapper()
7
bison
  • 739
  • 5
  • 21
  • Thanks for your comment. However, curiously enough, calling "MNL.load_data_wrapper2()" I get the error message "TypeError: load_data() missing 1 required positional argument: 'self'". On the other hand, calling "MNL.load_data_wrapper()" I get the desired output "7". Any idea why this is happening? – user810643 May 08 '19 at 23:09
  • @user810643 odd, I can not reproduce that issue. There is no argument in that method so that error is perplexing – bison May 08 '19 at 23:13
  • Defining `load_data_wrapper2` without any arguments will only work if you use `@staticmethod`. – Alasdair May 08 '19 at 23:17
  • My bad! I rebooted the Jupyter kernel, and now both "MNL.load_data_wrapper2()" and "MNL.load_data_wrapper()" give the desired output "7". – user810643 May 08 '19 at 23:17