2012-01-10 86 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