[python] Bound method error

I am creating a word parsing class and keep getting a "bound method Word_Parser.sort_word_list of <main.Word_Parser instance at 0x1037dd3b0>" error when I run this:

class Word_Parser:
    """docstring for Word_Parser"""
    def __init__(self, sentences):
        self.sentences = sentences

    def parser(self):
        self.word_list = self.sentences.split()

    def sort_word_list(self):
        self.sorted_word_list = self.word_list.sort()

    def num_words(self):
        self.num_words = len(self.word_list)

test = Word_Parser("mary had a little lamb")
test.parser()
test.sort_word_list()
test.num_words()
print test.word_list
print test.sort_word_list
print test.num_words

This question is related to python class

The answer is


This problem happens as a result of calling a method without brackets. Take a look at the example below:

class SomeClass(object):
    def __init__(self):
        print 'I am starting'

    def some_meth(self):
        print 'I am a method()'

x = SomeClass()
''' Not adding the bracket after the method call would result in method bound error '''
print x.some_meth
''' However this is how it should be called and it does solve it '''
x.some_meth()

For this thing you can use @property as an decorator, so you could use instance methods as attributes. For example:

class Word_Parser:
    def __init__(self, sentences):
        self.sentences = sentences

    @property
    def parser(self):
        self.word_list = self.sentences.split()

    @property
    def sort_word_list(self):
        self.sorted_word_list = self.word_list.sort()

    @property
    def num_words(self):
        self.num_words = len(self.word_list)

test = Word_Parser("mary had a little lamb")
test.parser()
test.sort_word_list()
test.num_words()
print test.word_list
print test.sort_word_list
print test.num_words

so you can use access the attributes without calling (i.e., without the ()).


You have an instance method called num_words, but you also have a variable called num_words. They have the same name. When you run num_words(), the function replaces itself with its own output, which probably isn't what you want to do. Consider returning your values.

To fix your problem, change def num_words to something like def get_num_words and your code should work fine. Also, change print test.sort_word_list to print test.sorted_word_list.


The syntax problem is shadowing method and variable names. In the current version sort_word_list() is a method, and sorted_word_list is a variable, whereas num_words is both. Also, list.sort() modifies the list and replaces it with a sorted version; the sorted(list) function actually returns a new list.

But I suspect this indicates a design problem. What's the point of calls like

test.parser()
test.sort_word_list()
test.num_words()

which don't do anything? You should probably just have the methods figure out whether the appropriate counting and/or sorting has been done, and, if appropriate, do the count or sort and otherwise just return something.

E.G.,

def sort_word_list(self):
   if self.sorted_word_list is not None:
      self.sorted_word_list = sorted(self.word_list)
   return self.sorted_word_list

(Alternately, you could use properties.)


I think you meant print test.sorted_word_list instead of print test.sort_word_list.

In addition list.sort() sorts a list in place and returns None, so you probably want to change sort_word_list() to do the following:

self.sorted_word_list = sorted(self.word_list)

You should also consider either renaming your num_words() function, or changing the attribute that the function assigns to, because currently you overwrite the function with an integer on the first call.


Your helpful comments led me to the following solution:

class Word_Parser:
    """docstring for Word_Parser"""
    def __init__(self, sentences):
        self.sentences = sentences

    def parser(self):
        self.word_list = self.sentences.split()
        word_list = []
        word_list = self.word_list
        return word_list

    def sort_word_list(self):
        self.sorted_word_list = sorted(self.sentences.split())
        sorted_word_list = self.sorted_word_list
        return sorted_word_list

    def get_num_words(self):
        self.num_words = len(self.word_list)
        num_words = self.num_words
        return num_words

test = Word_Parser("mary had a little lamb")
test.parser()
test.sort_word_list()
test.get_num_words()
print test.word_list
print test.sorted_word_list
print test.num_words

and returns: ['mary', 'had', 'a', 'little', 'lamb'] ['a', 'had', 'lamb', 'little', 'mary'] 5

Thank you all.