2012-01-10 31 views
7

Tôi có đoạn code sau đây, trong đó có hai vấn đề sau đây:phương pháp chính trong 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 

Mã này là từ một hướng dẫn, và trong hướng dẫn nó hoạt động tốt. Tôi có Python 2.7 và sử dụng plugin PyDev cho Eclipse.

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

Bạn có thể cung cấp liên kết đến hướng dẫn đó không? Ai viết nó nên bị bắn, hoặc ít nhất bị cấm viết nữa. Đó là * không * cách bạn viết các thuộc tính lớp trong Python. –

+2

Nghe Daniel và tra cứu trang trí '@ property' bằng Python. Bạn không phải viết getters và setters như thế. – katrielalex

+0

Cũng không sử dụng tên gạch dưới kép - chúng ở đó cho một trường hợp sử dụng rất cụ thể. Nếu bạn muốn chỉ ra rằng một thuộc tính là "chỉ sử dụng nội bộ" thì hãy sử dụng một dấu gạch dưới để thay thế. – katrielalex

Trả lời

33

Mã này:

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


if __name__ =='__main__':main() 

không phải ở trong lớp. Khi bạn mang nó ra ngoài (không thụt lề) nó sẽ hoạt động.

Vì vậy, sau khi uống đó vào tài khoản của nó sẽ giống như thế này:

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

Move cả main() phương pháp và if __name__ == '__main__' tuyên bố ra khỏi phạm vi của lớp. Hãy nhớ - số lượng khoảng trắng.

+3

Lập trình như Guido thụt vào nó, như nó đã được. – grifaton

1

Thụt lề của bạn bị tắt. Hãy nhớ rằng trong Python, số lượng thụt đầu dòng. Hãy thử:

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

Cấu trúc sau đây đáng giá trong hầu hết mã của bạn - đặc biệt nếu bạn đang chạy trong nhiều môi trường.

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

Chức năng chính bạn đã xác định có vẻ như nằm trong lớp Thú. Chính nên là một hàm (các lớp chứa các phương thức) bên ngoài lớp động vật. Bạn cũng nên có Animal lớp học của bạn kế thừa từ đối tượng tức là

lớp Thú (object):

22

Để hiểu tại sao những gì bạn đã viết thất bại, bạn cần biết một chút về cách định nghĩa lớp làm việc trong Python. Như bạn đã biết, Python là một ngôn ngữ thông dịch: có một chương trình đọc qua các tệp Python và thực thi chúng khi nó đi. Khi thông dịch viên bắt gặp định nghĩa lớp, nó thực hiện như sau:

  1. Tạo một không gian tên mới (bản ghi của tất cả các tên biến) trong đó các biến và phương thức lớp sẽ được lưu trữ.
  2. Trích xuất tất cả mã trong định nghĩa lớp (được xác định bằng thụt đầu dòng) và chạy mã đó. Điều này sẽ điền vào không gian tên mà nó vừa tạo ra.
  3. Tạo đối tượng lớp mới có không gian tên được đưa ra ở trên và với các lớp cơ sở được đưa ra trong định nghĩa.
  4. Liên kết tên của lớp với đối tượng này.

Vậy điều gì đã xảy ra khi bạn thụt lề chức năng main bên trong mã của bạn? Trong khi ở bước 2, bạn đã gọi tên Animal. Nhưng tên này không được xác định cho đến bước 4! Thật vậy, nó không thể được xác định ở giai đoạn bạn gọi nó, bởi vì đó sẽ là hình tròn. Khi bạn di chuyển main bên ngoài định nghĩa lớp, nó sẽ không được thực hiện cho đến sau khi các bước 1-4 đã được hoàn thành và do đó tên Animal sẽ bị ràng buộc.


Nhân tiện, mã bạn viết không phải là Python tốt. Bạn có lẽ nên cố gắng tìm một hướng dẫn tốt hơn; đề xuất thông thường là "Dive Into Python". Tôi đã viết lại nó vì nó nên được thực hiện:

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 - Thông tin rất hữu ích cho người muốn tìm hiểu lý do tại sao mọi thứ không hoạt động. – istruble

Các vấn đề liên quan