Home > Back-end >  Print class instance variable from another class method
Print class instance variable from another class method

Time:10-03

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.

CodePudding user response:

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.

CodePudding user response:

Defining the __str__() method should work:

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

    def __str__(self):
        return self.fullname

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

You don't need to call .__str__() explicitly. The f-string converts the values to strings automatically.

CodePudding user response:

Add this to your class:

  def __str__(self):
        return(f"{self.fullname}")

and then print(p1)

  • Related