Python Forum
Python classes - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Python classes (/thread-38642.html)



Python classes - PythonNewbee - Nov-08-2022

Hi People

I have some difficulty with classes in Python.
I want to call a method, belonging to class A, from class B. I looked at online examples and tested them successfully, but my code generates an error which I do not understand. I will attach the .py file for details, but in essence here is what I'm trying to do:
class A:
   def __init__(self,a,b):
      self.a_ = a
      self.b_ = b
   
  def set_a(self,aa):
     self.a_ = aa

class B:
   def __init__(self,c):
      self.c_ = c
   
    def set_a_of_classA(self,x):
       A.set_a(self,x)

def main():
   a = A(1,2)
   b = B(7)

   b.set_a_of_classA(10)
The code raises this error:
Error:
AttributeError: 'b' object has no attribute 'a_'



RE: Python classes - deanhystad - Nov-08-2022

Please wrap code in Python tags.

Class B is class A with extra stuff. B knows now to set_a. B inherited .set_a() from class A. There is no need for set_a_of_classA(). Just call b.set_a(value)
def set_a_of_classA(self,x):
    """There is no reason for this method to exist.  Call set_a() instead."""
    # But this is how it would be written
    self.set_a(self, x)
This is an error.
class B:
def __init__(self, c):
    self.c_ = c
You are not calling the __init__ method for class A. Attributes a and b are initialized in A.__init__(). Your code should look like this:
def __init__(self, a, b, c):
    super().__init__(a, b)
    self.c_ = c



RE: Python classes - PythonNewbee - Nov-09-2022

Hi deanhystad

Is inheritance the only way to achieve this?
I do not want to implement this via inheritance, because the 2 classes may not always be related.
Let me explain. I'm trying to write a simple table driven agent program (vacuum cleaner cleaning 2 rooms - the classic AI example). In this program the vacuum cleaner must set the room status to "clean" after cleaning it.
Thus, the vacuum object must call the room object's room.set_status('c').

In this scenario a room and a vacuum is not the same type of object and thus implementing inheritance between the room and vacuum classes does not make sense, not so?

Is there no other way to achieve this goal?


RE: Python classes - DeaD_EyE - Nov-09-2022

class A:
    def method(self):
        return 42


class B:
    def __init__(self, a_instance):
        self.a = a_instance


b = B(A())
print(b.a.method())
Or you can instanciate the class A directly in the __init__ method.
class A:
    def method(self):
        return 42


class C:
    def __init__(self):
        self.a = A()


print(C().a.method())
Method get_a from instance C calls method from instance A:
class A:
    def method(self):
        return 42


class C:
    def __init__(self):
        self.a = A()
    def get_a(self):
        return self.a.method()

print(C().get_a())
I prefer the composition pattern.


RE: Python classes - deanhystad - Nov-09-2022

Achieve what goal?