Goal: calculate a value based on the sum of attributes of another object, and an attribute from the current object an then use that value to subtract from another value
Expected Output: target_value = 5
Issue: AttributeError: type object ‘x’ has no attribute ‘attribute1’
Object 1:
class x():
def __init__(self, attribute1):
self.attribute1 = attribute1
Object 2:
from object_one import x
class y():
def __init__(self, attribute2):
self.attribute2 = attribute2
def calculate_attributes(self, target):
value = x.attribute1 + y.attribute2
target -= value
Main:
from object_one import x
from object_two import y
object_x = x(5)
object_y = y(10)
target_value = 20
object_y.calculate_attributes(target_value)
print(target_value)
>Solution :
A direct solution to your problem
In Object 1, you are declaring the field attribute1. In Object2, you are importing the class X.
The class X does not have an attribute of name attribute1
– only an object of type x
does. You would have to pass in a reference to the original object x
into the calculate_attributes(self, target)
method by adding a parameter, like below:
class y():
def __init__(self, attribute2):
self.attribute2 = attribute2
def calculate_attributes(self, target, x_obj):
value = x_obj.attribute1 + y.attribute2
target -= value
After that, you would use this calculate_attributes method by doing:
object_y.calculate_attributes(target_value, object_x)
A more in depth explanation – why did this happen?
A class is, basically, a blueprint for an object. After defining a class, you can use it by instantiating an object of its type.
With the line
object_x = x(5)
You are making an object of the type x.
This object has its own fields – it is alive on its own, and is simply created from the blueprint that is its class (herein: "type", "blueprint", "parent class" – all mean the same thing when I speak here).
In the __init__
method, when you set self.attribute2
to the parameter with the same name, you set a field of that any object of that class that is instantiated. This means that two y
type objects can have a different value of attribute2
However, you can also make the class contain a "field". This can be done like below:
class y():
who_made_this_class = "george"
def __init__(self, attribute2):
self.attribute2 = attribute2
This can be referred to as a static class variable. Now, when you instantiate a new y
object, you see the behaviour shown below:
obj_one = y(15);
obj_two = y(2020);
print("Object ones attribute2 value is: " + str(obj_one.attribute2))
print("Object twos attribute2 value is: " + str(obj_two.attribute2))
print("Object ones who_made_this_class value is: " + str(obj_one.who_made_this_class))
print("Object twos who_made_this_class value is: " + str(obj_two.who_made_this_class))
Expected output is:
Object ones attribute2 value is: 15
Object twos attribute2 value is: 2020
Object ones who_made_this_class value is: george
Object twos who_made_this_class value is: george