Peter Bucher
Peter Bucher

Reputation: 49

Confusion With OOP in Python

I'm trying to learn OOP in Python but I'm confused about some parts.

class Song(object):

    def __init__(self, lyrics):
        self.lyrics = lyrics

    def sing_me_a_song(self):
        for line in self.lyrics:
            print line

    def print_x(self):
        print x

happy_bday = Song(["Happy birthday to you,",
               "I don't want to get sued",
               "So I'll stop right there"])

bulls_on_parade = Song(["They'll rally around the family",
                    "With pockets full of shells"])

happy_bday.sing_me_a_song()

bulls_on_parade.sing_me_a_song()

x = Song(4)

x.print_x()

print_x() returns:

<__main__.Song object at 0x7f00459b4390>

instead of 4. So I try adding x to the parameters for __init__ and print_x, and changing print x to print self.x in the print_x function plus adding self.x = x to init, but it returns this:

TypeError: __init__() takes exactly 3 arguments (2 given)

I honestly don't know what's gone awry here. But any help would be hugely beneficial to me finally understand OOP.

Upvotes: 1

Views: 247

Answers (2)

user764357
user764357

Reputation:

This is less an OOP issue and more of a scoping issue. Lets examine a very cut down version.

class Song(object):
    def __init__(self, lyrics):
        self.lyrics = lyrics

    def print_x(self):
        print x

From here we instantiate x (in the local scope):

>>> x = Song(4)

Now, before we do anything, lets examine x:

>>> print x.lyrics
4

The reason is that when you called Song(4) the value 4 is determined to be lyrics by its position.

And when we call print_x:

>>> x.print_x()
<__main__.Song object at 0x7f00459b4390> # Or some other memory address

The reason is that the only x that Python is aware of is the local x we just made.

What happens when we start again and make y:

>>> y = Song(4)
>>> print y.print_x ()
NameError: global name 'x' is not defined

No x exists to print and it throws an exception.

Upvotes: 3

itzMEonTV
itzMEonTV

Reputation: 20369

I think you are trying like

def __init__(self, lyrics, x):
    self.lyrics = lyrics
    self.x = x
...
def print_x(self):
    print self.x

By this way it will produce TypeError: init() takes exactly 3 arguments (2 given)

You can find the error from this. When you creating Song instance like

happy_bday = Song(["Happy birthday to you,",
           "I don't want to get sued",
           "So I'll stop right there"])

You have to pass the value of x to the __init__().Thats why the error is showing.This can done by

 happy_bday = Song(["Happy birthday to you,",
           "I don't want to get sued",
           "So I'll stop right there"],
            'x-value')

OR Set default value for x

def __init__(self, lyrics, x="default value"):
    self.lyrics = lyrics
    self.x = x

Upvotes: 0

Related Questions