'AttributeError: 'function' object has no attribute 'apply_gravity'

So the problem I'm encountering is that I have a function in one file, then when I import that file to another file and try to run the function, I get an error message saying: AttributeError: 'function' object has no attribute 'apply_gravity'

This is the code for the file I'm importing from:

class Player(pygame.sprite.Sprite):
def __init__(self, pos):
    super().__init__()
    self.image = pygame.Surface((32, 64))
    self.image.fill('red')
    self.rect = self.image.get_rect(topleft = pos)
    
    # Player Movement
    self.direction = pygame.math.Vector2(0, 0)
    self.speed = 8
    self.gravity = 0.8
    self.jump_speed = -16

def get_input(self):
    
    self.direction.x = 0

    keys = pygame.key.get_pressed()
    
    if keys[pygame.K_RIGHT]:
        self.direction.x = 1
    elif keys[pygame.K_LEFT]:
        self.direction.x = -1
    else: 
        self.direction.x = 0

    if keys[pygame.K_SPACE]:
        self.jump()

def apply_gravity(self):
    self.direction.y += self.gravity
    self.rect.y += self.direction.y

def jump(self):
    self.direction.y = self.jump_speed

def update(self):
    self.get_input()
    

and this is the code where I try to import the function:

import pygame
from tiles import Tile, width
from Settings import tile_size, level_map
from player import Player

class level:
def __init__(self, level_data, surface):
    
    # level setup
    self.display_surface = surface
    self.setup_level(level_data)
    self.world_shift = 0
    
def setup_level(self, layout):
    self.tiles = pygame.sprite.Group()
    self.player = pygame.sprite.GroupSingle()
    for row_index, row in enumerate(layout):
        for column_index, column in enumerate(row):
            
            x = column_index * tile_size
            y = row_index * tile_size

            if column == 'X':
                tile = Tile((x, y), tile_size)
                self.tiles.add(tile)
            if column == 'P':
                player_sprite = Player((x, y))
                self.player.add(player_sprite)

def scroll_x(self):
    player = self.player.sprite
    player_x = player.rect.centerx
    direction_x = player.direction.x

    if player_x < width/4 and direction_x < 0:
        self.world_shift = 8
        player.speed = 0
    elif player_x > width - width/4  and direction_x > 0:
        self.world_shift = -8
        player.speed = 0
    else:
         self.world_shift = 0
         player.speed = 6

def horizontal_collision(self):
    player = self.player.sprite
    player.rect.x += player.direction.x * player.speed

    for sprite in self.tiles.sprites():
        if sprite.rect.colliderect(player.rect):
            if player.direction.x < 0:
                player.rect.left = sprite.rect.right
            elif player.direction.x > 0:
                player.rect.right = sprite.rect.left

def vertical_collision(self):
    player = self.player.sprites
    player.apply_gravity()

    for sprite in self.tiles.sprites():
        if sprite.rect.colliderect(player.rect):
            if player.direction.y > 0:
                player.rect.bottom = sprite.rect.top
                player.diretcion.y = 0
            elif player.direction.y < 0:
                player.rect.top = sprite.rect.bottom


def run(self):

    #Level Tiles

    self.tiles.update(self.world_shift)
    self.tiles.draw(self.display_surface)
    self.scroll_x()
    
    # Player

    self.player.update()
    self.horizontal_collision()
    self.vertical_collision()
    self.player.draw(self.display_surface)
    self.scroll_x()


Solution 1:[1]

Your problem, I believe, is that you are setting player to the sprites method of an object (a method is a "function") when what you want to do is call that method/function and then set player to its return value. So I think you want this:

player = self.player.sprites
player.apply_gravity()

to be this:

player = self.player.sprites()
player.apply_gravity()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 CryptoFool