numb3rs1x
numb3rs1x

Reputation: 5223

Converting functions into a methods of a class in python

I'm trying to get the hang of python 2.6, which is my introduction to a programming language. I'm following Learn Python the Hard Way and I must have missed something. I have a set of functions that I want to combine into a class. These functions are contained here. I tried to combine these into a class called "Parsers". This code is contained here.

The functions themselves work outside of the class. I'm trying to call the functions out of the class like this:

import the module:

>>> from ex48 import parser2

Assign the class:

>>> parser_class = parser2.Parsers()

Call a function:

>>> parser_class.parse_subject(word_list, ('noun', 'player'))

I get the following:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ex48/parser2.py", line 60, in parse_subject
    verb = parse_verb(word_list)
NameError: global name 'parse_verb' is not defined

Not sure why it's telling me that. Can someone point me in the right direction?

Upvotes: 1

Views: 3581

Answers (3)

Marcin
Marcin

Reputation: 49846

You are confused as to what your code is doing.

This does not assign, a class, it creates an instance, and assigns that instance to a variable:

parser_class = parser2.Parsers()

This calls a method on that instance:

parser_class.parse_subject(word_list, ('noun', 'player'))

The following tells you that there is no global function (or indeed variable of any type) parse_verb:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ex48/parser2.py", line 60, in parse_subject
    verb = parse_verb(word_list)
NameError: global name 'parse_verb' is not defined

I expect that you want to change that to verb = self.parse_verb(word_list), which will call the parse_verb method of the same object (self).

Upvotes: 3

abarnert
abarnert

Reputation: 365767

There are two problems here, one mechanical, one conceptual. I'll deal with the latter first.

The whole point of a class is that its instances represent some kind of object in your model of the world. For example, a "sentence" is an object, so it makes sense to have a class called Sentence, but a "parsers" is not an object, so Parsers is probably going to be a confused class. Looking at things less abstractly, a class usually has some kind of state, encapsulated in data members that its methods work on.

What you really have here is a parser function that returns a Sentence object (or raises a ParserError). This function could be a method of Sentence, or it could be a free function; it could also be a method of a Parser class if there were any reason for such an object to exist in your model, but there doesn't seem to be one.

If you're just looking to encapsulate all those helper functions so they don't litter the global namespace (a good idea in itself), you don't need to abuse a class to do that. Just make them local functions inside parse_sentence, or put them in a module called parsers.

Now, on to the mechanical problem: If you have a method in a class, you normally only call it through dot syntax: someObject.methodName(params). When a method calls another method of the same object, you use the special self parameter (which you've correctly listed as the first param of each method) to do that. So:

verb = self.parse_verb(word_list)
obj = self.parse_object(word_list)

… and so on for all the other method calls in your sample.

Not every language requires an explicit self like this. For example, in C++ or related languages (Java, C#, etc.), a method can call another method without specifying a target, and it's implicitly assumed that the target is this (the C++ equivalent of self).

Upvotes: 2

unutbu
unutbu

Reputation: 879691

It looks like you are working from a python interactive session.

If you've made any changes to parser2.py after importing parser2, then you have to

reload(parser2)

to make those changes known to the interactive interpreter.

Upvotes: 1

Related Questions