2012-05-18 44 views
6

請幫我理解這一點。我創建了一個非常簡單的程序來嘗試理解類。Python TypeError:'str'對象不能被類調用

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() 

的問題代碼

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

爲什麼調用類的實例波利行不通的方法?我很迷茫。我已經看過http://mail.python.org/pipermail/tutor/2003-May/022128.html和其他與此類似的Stackoverflow問題,但我沒有明白。非常感謝。

回答

3

Two有一個實例方法name()。所以Two.name指的是這個方法,下面的代碼工作正常:

Polly = Two() 
Two.name(Polly) 

然而,在__init__(),你將其設置爲一個字符串覆蓋name,所以任何時候你創建的Two一個新實例,該name屬性會參考到字符串而不是函數。這就是爲什麼以下失敗的原因:

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

只要確保您使用單獨的變量名稱爲您的方法和您的實例變量。

+0

非常感謝您的明確解釋。我有一個相關的問題。如果我不想設置一個初始名稱並通過raw_input設置名稱,該怎麼辦?如果我設置了'self.name = name self.gender = gender'和'init __(self,name,gender)',然後通過'Polly = Two(name,gender)''調用它,我會得到錯誤,所以我不清楚在這裏做什麼。 – user1186742

+0

想想我可能已經得到它。我只是將這些實例變量放入方法而不是__init__中,或者將它們設置爲空字符串。 – user1186742

+1

不要在類中做'raw_input'工作;分開的責任。人們不負責弄清他們的名字是什麼;他們的名字是在出生時分配的,呃創造。 –

3

您正在使用名爲name的方法覆蓋您的name屬性。重命名一些東西。

+0

明白了。謝謝! – user1186742

1

你有兩個變量一個名爲「name」的函數。命名其中一個不同,它應該工作。

+0

燈泡的時刻。謝謝! – user1186742

1

我強烈建議你養成仔細命名事物的習慣。正如你所看到的,即使是非常小的代碼片段,你也會遇到麻煩。你一定要非常仔細地閱讀Python風格的PEP。 http://www.python.org/dev/peps/pep-0008/

+0

謝謝。我會! – user1186742