tags:

views:

138

answers:

3

I'm working through O'Reilly's "Learning Python" and having a problem with classes. I think I understand the concept, but in practice have stumbled upon this problem. Fron page 88-89:

>>> class Worker:
def __innit__(self, name, pay):
    self.name=name
    self.pay=pay
    def lastName(self):
        return self.name.split()[-1]
    def giveRaise(self, percent):
        self.pay*=(1.0+percent)

Then the book says "Calling the class like a function generates instances of a new type ...etc" and gives this example.

bob = Worker('Bob Smith', 50000)

This gives me this error:

TypeError: this constructor takes no arguments.

And then I start muttering profanities. So what am I doing wrong here?

Thanks for the help.

+9  A: 

David, you've mis-typed __init__

The correct spelling is this:

def __init__(self, name, pay):
    self.name=name
    self.pay=pay
def lastName(self):
    return self.name.split()[-1]
def giveRaise(self, percent):
    self.pay*=(1.0+percent)
Chris R
8 second too far :-)
yogsototh
This is my emabarassed face. Thanks very much.
David
That sure is a lot of upvotes for preserving the OP's indentation mistake :)
Joe Holloway
Copy-paste is a harsh mistress, sometimes :) I'll confess, I didn't read the rest of the code once I'd spotted the initial error. Edited for correctness, now.
Chris R
+2  A: 

You wrote __innit__ instead of __init__.

In this way, you declared just another method in the class, not the special method called the constructor, which is by definition named __init__. This causes Python to generate a default constructor taking no arguments, hence the error message.

Thomas
This causes Python to generate a default constructor taking no arguments, hence the error message.Thanks for that.
David
+5  A: 

One misspelling: it's __init__, not __innit__ -- just one n.

You also have some indentation problems but I think those may be due to just copy-and-paste issues, or else you'd be getting SyntaxErrors before the TypeError you relate;-).

So your code should probably be:

class Worker(object):
    def __init__(self, name, pay):
        self.name=name
        self.pay=pay
    def lastName(self):
        return self.name.split()[-1]
    def giveRaise(self, percent):
        self.pay*=(1.0+percent)

I've also added the (object) to class Worker -- in Python 3.* it doesn't matter, but in 2.* it does (and even in 3.* it doesn't hurt, anyway;-). This makes the class "new style", which doesn't matter at very elementary levels but will as soon as you start wanting to do anything "cool and interesting" such as adding properties;-).

Alex Martelli
Thanks for the freebie (object) tip.:)
David
@David, you're welcome -- and make sure you also indent like in my answer, **not** like in @Chris's, or else those `lastName` and `giveRaise` would be nested functions within `__init__` and not visible outside of it!-)
Alex Martelli