How to add additional attributes to a class? - python

How would I add additional locationx and locationy variables to the lists while the program is running?
Example of the class:
class Building:
'Common base class for all buildings'
def __init__(self, name, hp, img, locationx, locationy, height, width):
self.name = name
self.hp = hp
self.img = img
self.locationx = locationx
self.locationy = locationy
self.height = height
self.width = width
building_shipyard = Building("Shipyard",500,shipyard,[1000,2500,5000],[1000,2500,5000],300,300)
For instance, after a user places a new building, I might want self.locationx and self.locationy to be updated from [1000,2500,5000] to [1000,2500,5000,7000].

Just access these attributes:
...
def place_building ():
global building_shipyard
...
building_shipyard.locationx = [1000,2500,5000,7000]
# or
building_shipyard.locationx.append(7000)

Related

I am creating my own class. There's a type error that _Screen.__init__() takes 1 positional argument but 4 were given. What am I doing wrong?

# Set up the screen
import turtle
class Screen(turtle.Screen()):
# Create and define an object
def __init__(self, title, bgcolor, height, width, tracer = 0):
turtle.Screen().__init__(self)
# Assign attribute to our instance
self.title = title
self.bgcolor = bgcolor
self.height = height
self.width = width
self.tracer = tracer
Your issue is that you are trying to inherit from a class instance rather than from a class. Note that when you are doing
class Screen(turtle.Screen()):
you are creating a new instance of the turtle._Screen class.
To fix this error, you just have to inherit from the right class as such:
class Screen(turtle._Screen):
# Create and define an object
def __init__(self, title, bgcolor, height, width, tracer = 0):
# Note that here I use super() to access the parent class instead of creating a new instance with turtle.Screen()
super().__init__(self)
# Assign attribute to our instance
self.title = title
self.bgcolor = bgcolor
self.height = height
self.width = width
self.tracer = tracer
Hope this helps you

Using Builder Pattern, I got AttributeError: 'NoneType' object has no attribute to builder class function

I try to instance my class that made by using builder pattern
class Cat:
def __init__(self,height,weight, color):
self.height = height
self.weight = weight
self.color = color
def print(self):
print("%d %d %s" %(self.height,self.weight,self.color))
class CatBuilder:
def __init__(self):
self.weight = None
self.height = None
self.color = None
def setWeight(self,weight):
self.weight = weight
def setHeight(self,height):
self.height = height
def setColor(self,color):
self.color = color
def build(self):
cat = Cat(self.height,self.weight,self.color)
return cat
then I use below code to run cat1.print()
#error version
cat1 = CatBuilder().setColor("red").setHeight(190).setWeight(80)
cat1.print()
#correct version
cat_builder = CatBuilder()
cat_builder.setColor("red")
cat_builder.setHeight(180)
cat_builder.setWeight(50)
cat2 = cat_builder.build()
cat2.print()
I think both of code is right, but #error version is not working..
How can I fix it??
I got my answer!
I have to append return self code like below:
class Cat:
def __init__(self,height,weight, color):
self.height = height
self.weight = weight
self.color = color
def print(self):
print("%d %d %s" %(self.height,self.weight,self.color))
class CatBuilder:
def __init__(self):
self.weight = None
self.height = None
self.color = None
def setWeight(self,weight):
self.weight = weight
return self
def setHeight(self,height):
self.height = height
return self
def setColor(self,color):
self.color = color
return self
def build(self):
cat = Cat(self.height,self.weight,self.color)
return cat

Class function doesn't return correct value

This is my code:
class Rectangle(object):
def __init__(self, height, width):
self.height = height
self.width = width
def __str__(self):
return '{} x {} = {}'.format(self.height, self.width, self.area)
def area(self):
self.area=self.height*self.width
return self.area
def primarySchool(height, width):
return str(Rectangle(height, width))
For input height=7 and width=4 the output is
>>> primarySchool(7, 4):
7 x 4 = <bound method _runjcbjp.<locals>.Rectangle.area of
<__main__._runjcbjp.<locals>.Rectangle object at 0x2b482cd637f0>>
instead of 7 x 4 = 28.
How can I fix this?
In your Rectangle class, the area member is defined as a method.
As a consequence, print(self.area) will give you the representation of that method object, which is that <...> thing.
What you want is the result of the area method, not the method itself.
Therefore, you need to call the method, by writing parentheses after its name.
Your code should be:
return '{} x {} = {}'.format(self.height, self.width, self.area())
Additionnally, be careful not to reassign the same name in your method.
In your area method, you write:
self.area = self.height * self.width
As a consequence, after the first call to instance.area(), the area member will be overwritten, from a function to a number.
Subsequent calls would thus fail, with something like "Int object is not callable".
area is a method of your class, so you have to call it to get the return value (and not the method itself).
But given the fact that you assign to self.area inside the method it seems like you want it as "cached" property (accessible without calling it explicitly):
class Rectangle(object):
def __init__(self, height, width):
self.height = height
self.width = width
def __str__(self):
return '{} x {} = {}'.format(self.height, self.width, self.area)
#property
def area(self): # cached version
try:
return self._area
except AttributeError:
self._area=self.height*self.width
return self._area
def primarySchool(height, width):
return str(Rectangle(height, width))
primarySchool(7, 4)
# '7 x 4 = 28'
Or as uncached version:
class Rectangle(object):
def __init__(self, height, width):
self.height = height
self.width = width
def __str__(self):
return '{} x {} = {}'.format(self.height, self.width, self.area)
#property
def area(self):
return self.height*self.width
Or just calculate it in the __init__ and also set it as attribute:
class Rectangle(object):
def __init__(self, height, width):
self.height = height
self.width = width
self.area = height * width
def __str__(self):
return '{} x {} = {}'.format(self.height, self.width, self.area)
You're trying to have both a function and property called "area".
Why not simply:
def area(self):
return self.height*self.width
Call with:
self.area()

Python inherit variables from parent class

Sorry if I don't explain it that well but I'll try my best:
So I want to inherit the variables from the Parent class, but I don't want to pass them again when creating an instance of the Child class because I think that is redundant. I just want to use the eye color from the Parent for example. See the example code below for what I mean
This is what works:
class Parent:
def __init__(self, eye_color, length):
self.eye_color = str(eye_color)
self.length = length
class Child(Parent):
def __init__(self, gender, eye_color, length):
super().__init__(eye_color, length)
self.gender = str(gender)
x = Parent("Blue", 2)
y = Child("Men", "Blue", 2)
print(x.eye_color, x.length)
print(y.gender, x.length)
This is what I somehow want:
class Parent:
def __init__(self, eye_color, length):
self.eye_color = str(eye_color)
self.length = length
class Child(Parent):
def __init__(self, gender):
super().__init__(eye_color, length)
self.gender = str(gender)
x = Parent("Blue", 2)
y = Child("Men")
print(x.length, x.eye_color)
print(y.gender, x.length)
What you ask does not make sense:
class Parent:
def __init__(self, eye_color, length):
self.eye_color = str(eye_color)
self.length = length
class Child(Parent):
def __init__(self, gender):
super().__init__(eye_color, length)
self.gender = str(gender)
x = Parent("Blue", 2)
y = Child("Men")
print(x.length, x.eye_color)
print(y.gender, x.length)
In child, the parameters eye_color and length come from nowhere.
rassar example is good if you want to reuse a parent object.
You can also do the following:
class Parent:
# def __init__(self, eye_color=(default value here), length=(default value here)):
def __init__(self, eye_color="", length=0):
self.eye_color = str(eye_color)
self.length = length
OR
class Parent:
def __init__(self, eye_color="", length=0):
self.eye_color = str(eye_color)
self.length = length
class Child(Parent):
def __init__(self, gender, *args, **kwargs):
super().__init__(*args, **kwargs)
self.gender = str(gender)
x = Parent("Blue", 2)
y = Child("Men") # Work with first example of Parent
y = Child("Men", eye_color="Blue", length=2) # Work with first
y = Child("Men", "Blue", 2) # Work with second example
print(x.length, x.eye_color)
print(y.gender, y.length)
You could try passing a Parent instance to the Child initializer...That's probably the closest you'll get.
class Parent:
def __init__(self, eye_color, length):
self.eye_color = str(eye_color)
self.length = length
class Child(Parent):
def __init__(self, gender, parent):
super().__init__(parent.eye_color, parent.length)
self.gender = str(gender)
x = Parent("Blue", 2)
y = Child("Men", x)
print(x.length, x.eye_color)
print(y.gender, x.length)
Another thing you could do is hold a last_parent variable:
global last_parent
class Parent:
def __init__(self, eye_color, length):
self.eye_color = str(eye_color)
self.length = length
last_parent = self
class Child(Parent):
def __init__(self, gender):
super().__init__(last_parent.eye_color, last_parent.length)
self.gender = str(gender)
x = Parent("Blue", 2)
y = Child("Men")
print(x.length, x.eye_color)
print(y.gender, x.length)

python3 class __init__ inheritance without defining parameters again

Is it possible to inherit a class and use its init function without declaring all parameters again in the child class?
I have a class with lots of parameters, but I don't want to use a list (**args). I wouldn't see my actual parameters:
class Table(object):
def __init_(self, name, height ...):
self.name = name
self.height = height
class RoundTable(Table):
def __init__(self, radius):
self.radius = radius
table = RoundTable(name = "Placeholder",
height = 10,
radius = 20)
Use the super class before assigning specfic args
def __init__(self,radius,*args,**kwargs):
super().__init__(*args,**kwargs)
self.radius = radius
Edit : I'm assuming you mean class and not a function

Categories