0

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.

2
  • 1
    It prints None also because in addition to printing within display_person you also print the return value of that function. "I have a class which initialises a person, then another class to handle the manipulation and displaying of that persons details." this is a bizarre separation of duties, fwiw. Commented Oct 2, 2022 at 17:07
  • Please show your __str__() method, that should have worked. Commented Oct 2, 2022 at 17:08

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I think he wants printing a Person to automatically show the fullname, using a __str__() method.
Thank you, I didn't know f-string called the str. To clarify, I plan to include more methods to show the other details of the Person (ie, id, email, address) so {person.fullname} is ideal
@Barmar yes I might end up just printing all Person details within a single function so that is also an option
1

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.

Comments

0

Add this to your class:

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

and then print(p1)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.