2012-07-04 19 views
5

Soy un poco nuevo en python, pero estoy familiarizado con OOP. Intento escribir un juego usando PyGame. Básicamente, mi objetivo es renderizar árboles cada pocos segundos y mover el árbol a través de la pantalla.AttributeError: La instancia de clase no tiene el método __call__

Así que aquí es mi código:

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

Pero cuando yo haga esto, los primeros árboles se generan con éxito pero luego la ventana PyGame cerradas y me sale este error:

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

Respuesta

19

Supongo que es porque tiene un nombre de variable tree (usado en tree.render()) que entra en conflicto con su nombre de clase. Llamarlo Tree sería mejor (y más pitónico ^^).

+0

tonto de mí no haber notado eso, gracias! :) –

+1

¡De nada! – Emmanuel

4

Usted Quizás desee llamar a la variable tree en el bucle for, que no sea tree. Está sombreando el nombre de la clase.

+0

Jaja, tan estúpido de mí. ¡Gracias! –

1

su contexto están contaminados

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

El compilador puede considera que no le init de la clase, pero pide su llamada función.

+1

En Python puede crear tipos invocables (tipos que implementan el operador 'llamar' a través de un método '__call__'), y la instanciación se realiza realmente llamando a la clase, que implementa el operador de llamada. IOW, todo lo que el compilador ve es una operación de 'llamada', cualquiera que sea su ejecución (e incluso el hecho de que el objeto al que se llama llama o no implementa el operador de llamada) se determina en tiempo de ejecución. –

Cuestiones relacionadas