220

I'm writing some code that takes a filename, opens the file, and parses out some data. I'd like to do this in a class. The following code works:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None

        def parse_file():
            #do some parsing
            self.stat1 = result_from_parse1
            self.stat2 = result_from_parse2
            self.stat3 = result_from_parse3
            self.stat4 = result_from_parse4
            self.stat5 = result_from_parse5

        parse_file()

But it involves me putting all of the parsing machinery in the scope of the __init__ function for my class. That looks fine now for this simplified code, but the function parse_file has quite a few levels of indention as well. I'd prefer to define the function parse_file() as a class function like below:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        parse_file()

    def parse_file():
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

Of course this code doesn't work because the function parse_file() is not within the scope of the __init__ function. Is there a way to call a class function from within __init__ of that class? Or am I thinking about this the wrong way?

Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
PythonJin
  • 4,034
  • 4
  • 32
  • 40
  • 3
    Is there any reason the code example needs five versions of "stat"? It would make it easier to read if there would be only one. – 465b Apr 29 '20 at 15:23

6 Answers6

299

Call the function in this way:

self.parse_file()

You also need to define your parse_file() function like this:

def parse_file(self):

The parse_file method has to be bound to an object upon calling it (because it's not a static method). This is done by calling the function on an instance of the object, in your case the instance is self.

Lewis Diamond
  • 23,164
  • 2
  • 24
  • 32
60

If I'm not wrong, both functions are part of your class, you should use it like this:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        self.parse_file()

    def parse_file(self):
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

replace your line:

parse_file() 

with:

self.parse_file()
Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
Paritosh Singh
  • 6,288
  • 5
  • 37
  • 56
18

How about:

class MyClass(object):
    def __init__(self, filename):
        self.filename = filename 
        self.stats = parse_file(filename)

def parse_file(filename):
    #do some parsing
    return results_from_parse

By the way, if you have variables named stat1, stat2, etc., the situation is begging for a tuple: stats = (...).

So let parse_file return a tuple, and store the tuple in self.stats.

Then, for example, you can access what used to be called stat3 with self.stats[2].

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • I agree, I just put the self.stat1 through self.stat5 in there to show that there were some class variables that I was assigning to. In the actual code I have a more elegant solution. – PythonJin Sep 28 '12 at 19:58
  • How should this be altered if I want to the `parse_file` function to be a method of the `MyClass` object. Where would `self` be necessary? – n1k31t4 Jul 01 '18 at 13:25
1

You must declare parse_file like this; def parse_file(self). The "self" parameter is a hidden parameter in most languages, but not in python. You must add it to the definition of all that methods that belong to a class. Then you can call the function from any method inside the class using self.parse_file

your final program is going to look like this:

class MyClass():
  def __init__(self, filename):
      self.filename = filename 

      self.stat1 = None
      self.stat2 = None
      self.stat3 = None
      self.stat4 = None
      self.stat5 = None
      self.parse_file()

  def parse_file(self):
      #do some parsing
      self.stat1 = result_from_parse1
      self.stat2 = result_from_parse2
      self.stat3 = result_from_parse3
      self.stat4 = result_from_parse4
      self.stat5 = result_from_parse5
Ionut Hulub
  • 6,180
  • 5
  • 26
  • 55
0

In parse_file, take the self argument (just like in __init__). If there's any other context you need then just pass it as additional arguments as usual.

Teo Klestrup Röijezon
  • 5,097
  • 3
  • 29
  • 37
-15

I think that your problem is actually with not correctly indenting init function.It should be like this

class MyClass():
     def __init__(self, filename):
          pass

     def parse_file():
          pass
Zed
  • 5,683
  • 11
  • 49
  • 81