How to pass an attribute from an object to another to calculate a value

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

Leave a Reply