227

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
7,0597 gold badges52 silver badges69 bronze badges
asked Sep 28, 2012 at 19:40
1
  • 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. Commented Apr 29, 2020 at 15:23

6 Answers 6

310

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.

answered Sep 28, 2012 at 19:45
Sign up to request clarification or add additional context in comments.

Comments

62

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
56.5k23 gold badges103 silver badges93 bronze badges
answered Sep 28, 2012 at 19:45

5 Comments

Could you explain why it must be used self.parse_file() and not parse_file()?
@paritoshsingh should def parse_file(self): not be nested under the __init__ function so that you don't have a partially initialised object?
@ivanleoncz As parse_file is instance method, we need to use reference object to call same.
@rong If this code is venerable and you don't want to allow setting parse file from outside, yes it should be nested.
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].

answered Sep 28, 2012 at 19:45

2 Comments

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.
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?
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
answered Sep 28, 2012 at 19:47

Comments

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.

answered Sep 28, 2012 at 19:47

Comments

-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
answered Sep 28, 2012 at 19:44

3 Comments

Neither is your code. Unless you put the @staticmethod decorator on top of parse_file
at least add the missing self in your parse_file method.
Oops, sorry there should have been an extra layer of indenting under the "class MyClass():" line. I've fixed it above, but the question remains the same.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.