2012-07-04 23 views
5

Tôi hơi mới với python, nhưng quen thuộc với OOP. Tôi đang cố viết một game bằng PyGame. Về cơ bản, mục tiêu của tôi là để làm cho cây mỗi vài giây và di chuyển cây rects trên màn hình.AttributeError: Class Instance không có phương thức __call__

Vì vậy, đây là mã của tôi:

from collections import deque 
import pygame,random,sys 

pygame.init() 
size = 800,600 
screen = pygame.display.set_mode(size) 

class tree: 
    def __init__(self): 
      self.img = pygame.image.load("tree.png") 
      self.rect = self.img.get_rect() 
    def render(self): 
      screen.blit(self.img,self.rect) 
    def move(self,x,y): 
      self.rect = self.rect.move(x,y) 

#creating a queue of trees 
trees = deque() 

#appending the first tree on to the queue 
trees.append(tree()) 


while 1: 


    for event in pygame.event.get(): 
      if event.type == pygame.QUIT: sys.exit() 

    #appending tree() to trees queue every 300 ms 
    if pygame.time.get_ticks() % 300 == 0: 
      trees.append(tree()) 

    #rendering and moving all the tree rects of trees in the queue 
    for tree in trees: 
      tree.render() 
      tree.move(20,2) 
    pygame.display.flip() 

Nhưng khi tôi thực hiện điều này một vài cây đầu tiên được tạo ra thành công nhưng sau đó cửa sổ Pygame đóng lại và tôi nhận được lỗi này:

Traceback (most recent call last): 
File "error.py", line 25, in <module> 
trees.append(tree()) 
AttributeError: tree instance has no __call__ method 

Trả lời

19

Tôi đoán đó là vì bạn có tên biến là tree (được sử dụng trong tree.render()) xung đột với tên lớp của bạn. Gọi nó là Tree sẽ tốt hơn (và nhiều hơn nữa là pythonic ^^).

+0

Ngớ ngẩn với tôi để không nhận thấy điều đó, cảm ơn! :) –

+1

Bạn được chào đón! – Emmanuel

4

Bạn có thể muốn gọi biến số tree trong vòng lặp for thứ gì đó khác với tree. Nó đang che giấu tên lớp.

+0

Haha, thật ngu ngốc với tôi. Cảm ơn! –

1

ngữ cảnh của bạn đều bị ô nhiễm

while 1: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: sys.exit() 

    #appending tree() to trees queue every 300 ms 
    if pygame.time.get_ticks() % 300 == 0: 
     trees.append(tree()) <----------------------- second time, this tree is not your class, but the last instance of tree 

    #rendering and moving all the tree rects of trees in the queue 
    for tree in trees: <-------------------- here, the last tree will get name with tree 
     tree.render() 
     tree.move(20,2) 
    pygame.display.flip() 

trình biên dịch có thể nghĩ rằng bạn đang không init lớp, nhưng gọi gọi của nó chức năng.

+1

Trong Python, bạn có thể tạo các kiểu có thể gọi (loại thực hiện toán tử 'call' thông qua phương thức '__call__'), và việc thực hiện instantiation được thực hiện bằng cách gọi lớp, thực hiện toán tử cuộc gọi. IOW, tất cả các trình biên dịch nhìn thấy là một cuộc gọi 'hoạt động', bất cứ điều gì nó được thực hiện trên (và thậm chí thực tế là các đối tượng được gọi là không thực hiện các nhà điều hành cuộc gọi) được xác định tại thời gian chạy. –

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