10.5. Stringify Objects

10.5.1. __str__()

  • for end-user

  • print converts it's arguments to str() before printing

Listing 224. Object without __str__() method overloaded prints their memory address
class Astronaut:
    def __init__(self, name):
        self.name = name


astro = Astronaut('Jose Jimenez')

str(astro)          # '<__main__.Astronaut object at 0x114175dd0>'
print(astro)        # <__main__.Astronaut object at 0x114175dd0>
Listing 225. Objects can verbose print if __str__() method is present
class Astronaut:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return f'My name... {self.name}'


astro = Astronaut('Jose Jimenez')

str(astro)          # 'My name... Jose Jimenez'
print(astro)        # My name... Jose Jimenez

10.5.2. __repr__()

  • for developers

  • object representation

  • copy-paste for creating object with the same values

  • useful for debugging

  • printing list will call __repr__ on each element

Listing 226. Using __repr__() on a class
class Astronaut:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f'Astronaut(name="{self.name}")'


 astro = Astronaut('Jose Jimenez')

 repr(astro)        # 'Astronaut(name="Jose Jimenez")'
 astro              # Astronaut(name="Jose Jimenez")
Listing 227. printing list will call __repr__ on each element
class Astronaut:
    def __init__(self, name):
        self.name = name

crew = [
    Astronaut('Jan Twardowski'),
    Astronaut('Mark Watney'),
    Astronaut('Melissa Lewis'),
]

print(crew)
# [
#   <__main__.Astronaut object at 0x107871160>,
#   <__main__.Astronaut object at 0x107c422e8>,
#   <__main__.Astronaut object at 0x108156be0>
# ]
Listing 228. printing list will call __repr__ on each element
class Astronaut:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f'{self.name}'

crew = [
    Astronaut('Jan Twardowski'),
    Astronaut('Mark Watney'),
    Astronaut('Melissa Lewis'),
]

print(crew)
# [Jan Twardowski, Mark Watney, Melissa Lewis]

10.5.3. __str__() vs. __repr__()

Listing 229. __str__ and __repr__
import datetime

str(datetime.datetime.now())
# 2019-01-05 20:15:00.927387

repr(datetime.datetime.now())
# datetime.datetime(2019, 1, 5, 20, 15, 0, 684972)

10.5.4. __format__()

  • Used for advanced formatting

class Astronaut:
    def __init__(self, name):
        self.name = name

    def __format__(self, mood):
        if mood == 'happy':
            return f"Yuppi, we're going to space!"
        elif mood == 'scared':
            return f"I hope we don't crash"


 astro = Astronaut('Jose Jimenez')

 print(f'{astro:happy}')
 # Yuppi, we're going to space!

 print(f'{astro:scared}')
 # I hope we don't crash
class Point:
    def __init__(self, x, y, z=0):
        self.x = x
        self.y = y
        self.z = z

    def __format__(self, name):

        if name == 'in_2D':
            return f"({self.x}, {self.y})"

        if name == 'in_3D':
            return f"({self.x}, {self.y}, {self.z})"

        if name == 'as_dict':
            return str(self.__dict__)

        if name == 'as_tuple':
            return str(tuple(self.__dict__.values()))

        if name == 'as_json':
            import json
            return json.dumps(self.__dict__)


point = Point(x=1, y=2)

print(f'{point:in_2D}')           # '(1, 2)'
print(f'{point:in_3D}')           # '(1, 2, 0)'
print(f'{point:as_tuple}')        # '(1, 2, 0)'
print(f'{point:as_dict}')         # "{'x': 1, 'y': 2, 'z': 0}"
print(f'{point:as_json}')         # '{"x": 1, "y": 2, "z": 0}'

10.5.5. Assignments

10.5.5.1. Stringify Object

English

#. Modify code from input data (see below) #. Overload str and repr to achieve result of printing

Polish
  1. Zmodyfikuj kod z danych wejściowych (patrz sekcja input)

  2. Przeciąż str i repr aby osiągnąć rezultat wyświetlania

The whys and wherefores
Input
Listing 230. Address Book
class Crew:
    def __init__(self, members=()):
        self.members = list(members)

class Astronaut:
    def __init__(self, name, experience=()):
        self.name = first_name
        self.experience = list(experience)

class Mission:
    def __init__(self, year, name):
        self.year = year
        self.name = name
Output
melissa = Astronaut('Melissa Lewis')

print(f'Commander: \n{melissa}\n')
# Commander:
# Melissa Lewis
mark = Astronaut('Mark Watney', experience=[
    Mission(2035, 'Ares 3'),
])

print(f'Space Pirate: \n{mark}\n')
# Space Pirate:
# Mark Watney veteran of [
#       2035: Ares 3]
crew = Crew([
    Astronaut('Jan Twardowski', experience=[
        Mission(1969, 'Apollo 11'),
        Mission(2024, 'Artemis 3'),
    ]),
    Astronaut('José Jiménez'),
    Astronaut('Mark Watney', experience=[
        Mission(2035, 'Ares 3'),
    ]),
])

print(f'Crew: \n{crew}')
# Crew:
# Jan Twardowski veteran of [
#       1969: Apollo 11,
#       2024: Artemis 3]
# José Jiménez
# Mark Watney veteran of [
#       2035: Ares 3]