AttributeError : Class Instance has no __call__ method

37,329

Solution 1

I guess it's because you have a variable name tree (used in tree.render()) which conflicts with your class name. Calling it Tree would be better (and more pythonic ^^).

Solution 2

You might want to call the tree variable in the for loop something other than tree. It's shadowing the class name.

Solution 3

your context are polluted

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

the compiler may thinks you are not init the class, but calls its call function.

Share:
37,329
Admin
Author by

Admin

Updated on July 05, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm a bit new to python, but familiar with OOP. I'm trying to write a game using PyGame. Basically, my aim is to render trees every few seconds and move the tree rects across the screen.

    So here is my code:

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

    But when I execute this the first few trees are generated successfully but then the PyGame window closed off and I get this error:

    Traceback (most recent call last):
    File "error.py", line 25, in <module>
    trees.append(tree())
    AttributeError: tree instance has no __call__ method
    
  • bruno desthuilliers
    bruno desthuilliers almost 12 years
    In Python you can create callable types (types that implement the 'call' operator thru a __call__ method), and instantiation is actually performed by calling the class, which does implement the call operator. IOW, all the compiler sees is a 'call' operation, whatever it is performed on (and even the fact that the object being called does or not implement the call operator) being determined at runtime.