Search code examples
pythonclass-method

Print class instance variable from another class method


I have a class which initialises a person, then another class to handle the manipulation and displaying of that persons details. When I try to use the display_person method it prints the class instance rather than the fullname. I tried adding dunder methods __str__ and __repr__ however that doesn't resolve it.

import itertools

class Person:

    num_of_emps = 0
    id_iter = itertools.count(1)

    def __init__(self, firstname: str, surname: str, address: str, email: str):
        self.firstname = str(firstname)
        self.surname = str(surname)
        self.fullname = str(firstname) + ' ' + str(surname)
        self.email = str(email)
        self.address = str(address)

        person_id = next(self.id_iter)
        self.person_id = int(person_id)
        Person.num_of_emps += 1


class PersonActions:
    def display_person(self, fullname) -> None:
        print(f'This is {fullname.__str__()}.')

p1 = Person('Lucas', 'S', '100 st', '[email protected]')
p2 = Person('Rosie', 'B', '101 st', '[email protected]')
action = PersonActions()
print(action.display_person(p1))

The output is:

This is <__main__.Person object at 0x10aeebe20>.
None.

Would the architecture be better if I added the display_person method to the Person class directly? From research I have seen that its better to keep these methods separate for cohesion purposes as per this. How can I get the display_person method to print the full name? I plan to do the same with other details later on.

Why does it print 'None' also?

I have looked at class employee print method but still can't figure it out.


Solution

  • You pass in an instance of Person, so you should handle it as such in your other class:

    class PersonActions:
        def display_person(self, person) -> None:
            print(f'This is {person.fullname.__str__()}.')
    

    Actually you don't need the .__str()__, nor do you need the print() when you are calling this method:

    class PersonActions:
        def display_person(self, person) -> None:
            print(f'This is {person.fullname}.')
    
    p1 = Person('Lucas', 'S', '100 st', '[email protected]')
    p2 = Person('Rosie', 'B', '101 st', '[email protected]')
    action = PersonActions()
    action.display_person(p1)
    

    Update:

    or you meant to include a __str__() method like this:

    class Person:
        ...   # Current implementation elided - see code from OP
        def __str__(self):
            return self.fullname
    
    class PersonActions:
        def display_person(self, person) -> None:
            print(f'This is {person}.')
    

    The f-string formatting will automatically call the __str__() method for you.