2012-01-10 87 views
7

我有下面的代碼,它具有以下兩個問題:主要方法在Python

Traceback (most recent call last): 
    File "C:\Users\v\workspace\first\src\tests.py", line 1, in <module> 
    class Animal: 
    File "C:\Users\v\workspace\first\src\tests.py", line 39, in Animal 

    File "C:\Users\v\workspace\first\src\tests.py", line 31, in main 
    dog = Animal() 
NameError: global name 'Animal' is not defined 

此代碼是從一個教程,並在本教程中正常工作。我有Python 2.7並使用Eclipse的PyDev插件。

class Animal: 
    __hungry = "yes" 
    __name = "no name" 
    __owner = "no owner" 

    def __init__(self): 
     pass 

    def set_owner(self,newOwner): 
     self.__owner= newOwner 
     return 

    def get_owner(self): 
     return self.__owner 

    def set_name(self,newName): 
     self.__name= newName 
     return 

    def get_name(self): 
     return self.__name 

    def noise(self): 
     print('errr') 
     return 

    def __hiddenmethod(self): 
     print("hard to find") 


    def main(): 
     dog = Animal()  
     dog.set_owner('Sue') 
     print dog.get_owner() 
     dog.noise() 


    if __name__ =='__main__':main() 
+7

您能否提供該教程的鏈接?無論誰寫它,都應該被槍殺,或者至少被禁止再寫作。這不是*你如何在Python中編寫類屬性。 – 2012-01-10 21:54:39

+2

收聽Daniel,並在Python中查找「@ property」裝飾器。你不必寫這樣的getter和setter。 – katrielalex 2012-01-10 22:10:32

+0

也不要使用雙下劃線的名字 - 它們在那裏用於非常特殊的用例。如果您想指出某個屬性「僅供內部使用」,請改用單下劃線。 – katrielalex 2012-01-10 22:11:58

回答

33

此代碼:

def main(): 
    dog = Animal()  
    dog.set_owner('Sue') 
    print dog.get_owner() 
    dog.noise() 


if __name__ =='__main__':main() 

不應該在課堂上。當你把它放在外面(不縮進)它應該可以工作。

所以考慮到這一點後,就應該是這樣的:

class Animal: 
    __hungry = "yes" 
    __name = "no name" 
    __owner = "no owner" 

    def __init__(self): 
     pass 

    def set_owner(self,newOwner): 
     self.__owner= newOwner 
     return 

    def get_owner(self): 
     return self.__owner 

    def set_name(self,newName): 
     self.__name= newName 
     return 

    def get_name(self): 
     return self.__name 

    def noise(self): 
     print('errr') 
     return 

    def __hiddenmethod(self): 
     print("hard to find") 


def main(): 
    dog = Animal()  
    dog.set_owner('Sue') 
    print dog.get_owner() 
    dog.noise() 


if __name__ =='__main__': 
    main() 
1

同時移動main()方法和if __name__ == '__main__'聲明瞭類的範圍。記住 - 空白的數量。

+3

編程爲Guido縮進它,因爲它。 – grifaton 2012-01-10 21:33:31

1

您的縮進已關閉。請記住,在Python中,縮進計數。嘗試:

class Animal: 
    __hungry = "yes" 
    __name = "no name" 
    __owner = "no owner" 

    def __init__(self): 
     pass 

    def set_owner(self,newOwner): 
     self.__owner= newOwner 
     return 

    def get_owner(self): 
     return self.__owner 

    def set_name(self,newName): 
     self.__name= newName 
     return 

    def get_name(self): 
     return self.__name 

    def noise(self): 
     print('errr') 
     return 

    def __hiddenmethod(self): 
     print("hard to find") 

def main(): 
    dog = Animal()  
    dog.set_owner('Sue') 
    print dog.get_owner() 
    dog.noise() 


if __name__ =='__main__':main() 
2

以下構建體值得您的大部分代碼 - 尤其是如果您在多個環境中運行時。

if __name__ =='__main__': 
    main() 
0

您定義的主函數看起來像它在Animal類中。 Main應該是動物類之外的一個函數(類包含方法)。你也應該有你的類動物從對象繼承即

類動物(對象):

22

要了解爲什麼你寫的失敗是什麼,你需要了解類的定義Python中是如何工作的一點點。您可能知道,Python是一種解釋型語言:有一個程序可以讀取Python文件並在執行時執行它們。當解釋器遇到一個類定義,它執行以下操作:

  1. 創建一個新的命名空間(所有的變量名的紀錄),其中類變量和方法將被保存。
  2. 提取類定義內的所有代碼(由其縮進確定)並運行該代碼。這將填充它剛剛創建的名稱空間。
  3. 創建一個新的類對象,其名稱空間是上面給出的名稱空間,並且具有定義中給出的基類。
  4. 將此類的名稱綁定到此對象。

那麼在代碼中縮進main函數時發生了什麼?在步驟2中,您提到名稱Animal。但是這個名字在第四步之前沒有定義!的確,不能在您提及的階段定義爲,因爲那將是循環的。當您將main移到類定義之外時,它將不會執行,直到步驟1-4完成後,因此名稱Animal已經被綁定。


順便說一句,你寫的代碼不是很好的Python。您應該嘗試找到更好的教程;通常的建議是「潛入Python」。我已經重寫了它,因爲它應該這樣做:

class Animal(object): 
    def __init__(self, hungry="yes", name=None, owner=None): 
      self.hungry = hungry 
      self.name = name 
      self.owner = owner 

    def noise(self): 
        print('errr') 

    def _internal_method(self): 
        print("hard to find") 

    if  __name__ =='__main__': 
      dog = Animal()     
      dog.owner = 'Sue' 
      print dog.owner 
      dog.noise() 
+3

+1 - 非常有用的信息,爲想知道爲什麼事情不起作用的人。 – istruble 2012-01-10 22:27:41