Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python TypeError: 'str' object is not callable for class

Tags:

python

class

Please help me understand this. I created a really simple program to try to understand classes.

class One(object):
    def __init__(self, class2):
        self.name = 'Amy'
        self.age = 21
        self.class2 = class2

    def greeting(self):
        self.name = raw_input("What is your name?: ")
        print 'hi %s' % self.name

    def birthday(self):
        self.age = int(raw_input("What is your age?: "))
        print self.age 

    def buy(self):
        print 'You buy ', self.class2.name

class Two(object):
    def __init__(self): 
        self.name = 'Polly'
        self.gender = 'female'

    def name(self):
        self.gender = raw_input("Is she male or female? ")
        if self.gender == 'male'.lower():
            self.gender = 'male'
        else:
            self.gender = 'female'

        self.name = raw_input("What do you want to name her? ")

        print "Her gender is %s and her name is %s" % (self.gender, self.name)

Polly = Two()
Amy = One(Polly) 
# I want it to print 


Amy.greeting()
Amy.buy() 
Amy.birthday()

THE PROBLEM CODE

Polly.name() # TypeError: 'str' object is not callable
Two.name(Polly)# Works. Why?

Why does calling the method on the class instance Polly not work? I'm pretty lost. I've looked at http://mail.python.org/pipermail/tutor/2003-May/022128.html and other Stackoverflow questions similiar to this, but I'm not getting it. Thank you so much.

like image 441
user1186742 Avatar asked May 18 '12 17:05

user1186742


1 Answers

The class Two has an instance method name(). So Two.name refers to this method and the following code works fine:

Polly = Two()
Two.name(Polly)

However in __init__(), you override name by setting it to a string, so any time you create a new instance of Two, the name attribute will refer to the string instead of the function. This is why the following fails:

Polly = Two()      # Polly.name is now the string 'Polly'
Polly.name()       # this is equivalent to 'Polly'()

Just make sure you are using separate variable names for your methods and your instance variables.

like image 98
Andrew Clark Avatar answered Sep 26 '22 02:09

Andrew Clark