How do I instantiate an instance of a class in Python? - python

I'm new to python and doing some practice for uni,
I'm familiar with java so I am trying to create a class in python and then create an instance of the class to be used as an object from another file in the same directory.
so here's how I'm trying to do it:
within main.py -
import player
p1 = player.Player(300, 300, 64, 64)
here's my Player class located in player.py
import main
class Player:
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 15
self.left = False
self.right = False
self.walkCount = 0
this results in:
AttributeError: module 'player' has no attribute 'Player'
After some research I have also tried:
from player import Player
p1 = Player(300, 300, 64, 64)
which results in: ImportError: cannot import name 'Player' from 'player' (C:\Users\Alex\PycharmProjects\BunkerGame\player.py)
quite simply and ignoring some other code this should create an instance of the Player class in player.py to be used within the main.py file

As you noted in the comment, you import main into player - which means you have a circular import: Python can't resolve this so raises an attribute error.
You shouldn't need to do that. There shouldn't be anything in main that is needed by player. If there is, move it to player itself or a third module.

From the error you mentioned you most likely have a module already installed called player, which Python is importing as opposed to your local file player.py. Try renaming the file player.py to something else, or going on console and doing pip uninstall player.
Notice how the error says cannot import name 'Player' from 'player', which means Python is accessing a module called player, but is unable to access the class Player.

As #Daniel Roseman pointed out, I had 'import main' within player.py which python doesn't like apparently, removing this and any related code fixed the issue!

You just should write the import just like this:
import Player
p1 = Player(300, 300, 64, 64)
You can also write something like:
import Player as p
p1 = p(300, 300, 64, 64)

You need to remove the player. You are passing a class through as an attribute by using . which is the reason for the first error and the second is that your importing main on your player page and importing player on your main page. Just get rid of import main on your player page.
The first error:
import player
p1 = player.Player(300, 300, 64, 64)
This should just be:
import player
p1 = Player(300, 300, 64, 64)
Here is an example of whats happened:
class Player:
def __init__(self, name, age):
self.name = name
self.age = age
player = Player # setting the class to variable
player.name = 'Johnny' # .name is the attribute of the Player class
print(player.name)
Output:
'Johnny'
You have done this:
player.Player.name = 'Johnny'
print(player.name)
Which returns your error:
Traceback (most recent call last): File "main.py",
line 8, in <module>
player.Player.name = 'Johnny'AttributeError: type object 'Player' has no attribute 'Player'

Related

Attribute Error when using Turtles in Python

I am trying to build snake from turtles but am running into an attribute error when using the .xcor(), .ycor(), .pos() functions from the turtle class. Basically anything that returns a value from the turtle class is not working in my program. Here is my code:
from turtle import Turtle, Screen
import time
import random
screen = Screen()
class Snake(Turtle) : ## create snake class and pass Turtle class into it
def __init__(self):
self.xcors = []
self.ycors = []
self.snakesegs = []
self.create_snake()
def create_snake(self):
N = 0
for segs in range(1,4):
super().__init__(shape="square")
self.color("black")
self.penup()
self.goto(N,0)
self.snakesegs.append(super().__init__)
N -= 20
xcor = super().__init__.xcor()
ycor = super().__init__.ycor()
self.xcors.append(xcor)
self.ycors.append(ycor)
and here is the traceback I am getting:
Traceback (most recent call last):
File "/Users/gcinco/Documents/Python/Jett-Black/SNAKE/snake.py", line 49, in <module>
snape = Snake()
File "/Users/gcinco/Documents/Python/Jett-Black/SNAKE/snake.py", line 13, in __init__
self.create_snake()
File "/Users/gcinco/Documents/Python/Jett-Black/SNAKE/snake.py", line 24, in create_snake
xcor = super().__init__.xcor()
AttributeError: 'function' object has no attribute 'xcor'
If anyone has any idea what is going on please help, thanks!
You are calling superclass's constructor when calling super().__init__().
if you are trying to to call super's methods, just do
xcor = super().xcor()
ycor = super().ycor()
super().__init__ is the initialization method of class Turtle. It has no xcor or ycor attribute. I think what you intend is to call the x|y cor methods on the segment you created, which is much simpler:
segment = super().__init__(shape="square")
self.xcors.append(segment.xcor())
self.ycors.append(segment.ycor())
You might have an even easier time with simply:
self.segments = [super().__init__(shape="square") for _ in range(4)]
Then loop through the segments to set the desired characteristics of each:
self.color("black")
for square in self.segments:
# draw each segment in turn

Simple question: why 'list' object has no attribute 'x'

I am sorry if this is simple but I can't find an answer. I am trying to get random enemies in pygame (they should be same but spawn random).
So I have class:
class Enemy(object):
def __init__(self, ...):
...
self.visible = True
#and then I wanna make a list of this object
E1 = []
#in my while loop
while True:
...
if event.type == USEREVENT+2:
EN1.append(Enemy(10, 20, 64, 64, 259))
if len(enemy_bullets) < 1:
rocks.append(ro((round(EN1.x + EN1.width//2) - 30), (round(EN1.y + EN1.height//2) - 50), 23, 23))
I imported * from pygame.locals and in the beginning I set
pygame.time.set_timer(USEREVENT+2, random.randint(1000, 5000))
My error is 'list' object has no attribute 'x' and if I comment this I got another error in if E1.visible == True: ... it says: 'list' object has no attribute 'visible'.
Why?
Like #dcg said in the comments, EN1 is a list. You are appending to that list and then within that list you have your object of class Enemy. If you want to access a property in one of your enemy you need to index into that list (i.e. EN1[index of your enemy]) then access the variable inside, for example:
EN1[index].x

Issue with passing attributes between classes in python

Ive made these classes below and I'm trying to have a tile in the game present a text based on an attribute in another class. I keep getting this error.
File "C:\Users\xxxxxxxx\PycharmProjects\Game.idea\Girls.py", line 20, in not_interested
return (self.interest < 10)
AttributeError: 'GirlTile' object has no attribute 'interest'
class Girls():
def __init__(self):
self.girlnames = ["Lucy", "Cindy", "April", "Allison", "Heather", "Andrea", "Brittany", "Jessica", "Lane", "Lauren", "Sabrina","Chelsea","Amber"]
self.name = random.choice(self.girlnames)
self.height = random.randrange(60, 72)
self.age = random.randrange(18, 25)
self.number = self.new_number()
self.interest = 0
def not_interested(self):
return (self.interest < 10)
from Girls import Girls
class GirlTile(MapTile):
def __init__(self,x,y):
self.enemy = Girls()
super().__init__(x, y)
def intro_text(self):
self.stance = Girls.not_interested(self)
if self.stance:
print("Hey whats up")
It looks like not_interested is an instance-level method, but you are trying to call it with a class (Girls). And the call is sort of "working" because you are passing the GirlTile instance in the call -- hence the error that the GirlTile has no interest attribute (because it does not).
Maybe you intended this instead?
def intro_text(self):
# Use an actual Girl instance to call not_interested().
self.stance = self.enemy.not_interested()
...

Syntax Error; Python game spits out super method and imports

I made classes for what will basically become a BreakOut game, but I keep getting error messages. The nature of which always seem to surround two things; Class imports and the infamous "super" method. Usually in the form of a syntax error
I had some questions shot down in the past, so I will try to be as clear as I possibly can.
The main code for the game is as such...
import pygame
from Game import *
from Game.Scenes import *
from Game.Shared import *
class BreakOut:
def __init__(self):
self.__lives = 5
self.__score = 0
self.__level = Level(self)
self.__level.load(0)
self.__pad = Pad((0,0), 0)
self.__balls = [Ball((0,0), 0, self)]
pygame.init()
pygame.mixer.init()
pygame.display.set_caption("This is the Title of the Game")
self.__clock= pygame.time.Clock()
self.screen = pygame.display.set_mode(GameConstants.SCREEN_SIZE, pygame.DOUBLEBUF, 32)
pygame.mouse.set_visible(0)
self.__scenes = (
PlayingGameScene(self),
GameOver(self),
HighScoreScene(self),
MenuScene(self)
)
self.__currentScene = 0
self.__sounds = ()
def start(self):
while 1:
self.__clock.tick(100)
self.screen.fill((0,0,0))
currentScene = self.__scenes[self.__currentScene]
currentScene.handleEvents(pygame.event.get())
currentScene.render()
pygame.display.update()
def changeScene(self, scene):
pass
def getLevel(self):
pass
def getScore(self):
pass
def increaseScore(self, score):
pass
def getLives(self):
pass
def getBalls(self):
pass
def getPad(self):
pass
def playSound(self, soundClip):
pass
def reduceLives(self):
pass
def increaseLives(self):
pass
def reset (self):
pass
BreakOut().start()
At this stage, its only supposed to return a black screen, but instead it keeps giving me a error message with this traceback:
Traceback (most recent call last):
File "/Users/Ryan/PycharmProjects/Demo 1/Game/BreakOut.py", line 3, in <module>
from Game import *
File "/Users/Ryan/PycharmProjects/Demo 1/Game/__init__.py", line 9, in <module>
from Game.BreakOut import BreakOut
File "/Users/Ryan/PycharmProjects/Demo 1/Game/BreakOut.py", line 4, in <module>
from Game.Scenes import *
File "/Users/Ryan/PycharmProjects/Demo 1/Game/Scenes/__init__.py", line 3, in <module>
from Game.Scenes.HighScoreScene import HighScoreScene
File "/Users/Ryan/PycharmProjects/Demo 1/Game/Scenes/HighScoreScene.py", line 7
SyntaxError: invalid syntax
The bottom one connects to another class of code that looks like this:
from Game.Scenes.Scene import Scene
class HighScoreScene(Scene):
def __init__(self, game):
super(HighScoreScene, self.__init__(game)
PyCharm seems to highlight "super" and tells me "Old-style class contains call for super method" I don't know if that's important or not, but its something I've noticed consistently throughout the code.
I'm pretty sure its a simple mistake. Might be a typo, but I can't pinpoint it for the life of me. Please help!
super(HighScoreScene, self.__init__(game) # <- missing paren
It should be super(HighScoreScene, self).__init__(game)
And use object class BreakOut(object) if you want to use super.
New-style and classic classes
Your class Breakout line is not in line with the rest of your program (ahead by one space). If you backspace that line by one, everything should be fine (including #Padraic Cunningham 's answer).

Error: unbound method Dragon( ) must be called with Enemy instance as first argument (got Player instance instead)

class Character:
def __init__(self):
self.name = ""
self.health = 1
self.health_max = 1
class Player(Character):
def __init__(self):
Character.__init__(self)
self.state = 'normal'
self.health = 10
self.health_max = 10
class Monster(Character):
def Dragon(self):
self.name = "Dragon"
self.health = 20
def Goblin(self):
name = "Goblin"
health = 5
p = Player()
p.name = raw_input("Please enter your name: ")
print p.name
print p.state
print p.health
print p.health_max
m = Monster()
enemy = m.Dragon
print enemy.name
print enemy.health
Sorry, I've made this a little simpler to explain what I'm having difficulty with. I'm having a little bit of trouble with the basics of OOP, and I'm running into an issue with this snippet of code. I'm trying to create a "Dragon" here but I'm running into the following error:
Traceback (most recent call last):
File "test2.py", line 32, in
print enemy.name
AttributeError: 'function' object has no attribute 'name'
Can you tell me what I'm doing wrong here? Thanks.
You have to create an instance of a class first before you call any functions from it:
myenemy = Enemy()
myenemy.Dragon()
In your code, it looks like you created self.enemy, but later you call self.enemy = Enemy.Dragon(self). Instead of this last line, put self.enemy = self.enemy.Dragon(self).
It seems to be a recurring issue in the rest of your code as well. Commands = {'explore': Player.explore} should probably be Commands = {'explore': p.explore} (after you have created the instance p).
Since your updated code, I think you're getting functions and classes mixed up. Dragon is a function, and when you do enemy = m.Dragon, you are simply copying the function onto enemy. And thus when you do enemy.name, thinking it's a class, an error is raised, because enemy is now a function, not an instance.
You will have to create separate classes for different monsters:
class Dragon:
self.name = "Dragon"
self.health = 20
class Goblin:
name = "Goblin"
health = 5

Categories

Resources