Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__str__ method not working when objects are inside a list or dict

Tags:

python

class

In this example, the first print statement outputs the string returned by ball.__str__(), while the other two do not:

class Ball:

    def __init__(self, parent, xpos = 50, ypos = 50, radius = 100, vx = 0, vy = 0, mass = 1):
        """
        x,y are positions
        vx and vy are velocities in cells/second
        """
        self.x = xpos
        self.y = ypos
        self.r = radius
        self.vx = vx
        self.vy = vy
        self.mass = mass
        self.board = parent

    def __str__(self):
        return "Ball: x={0}, y={1}, r={2}, vx={3}, vy={4}".format(self.x,self.y,self.r,self.vx,self.vy)

class Board:

    def __init__(self, width = 100, height = 100, sps = 2):
        pass

board = Board()

ball = Ball(board)
ball_list = [Ball(board), Ball(board)]
ball_dict = {'ball_1':Ball(board), 'ball_2':Ball(board)}

print(ball)
print(ball_list)
print(ball_dict)

output:

Ball: x=50, y=50, r=100, vx=0, vy=0
[<__main__.Ball object at 0x106f79f98>, <__main__.Ball object at 0x106f79fd0>]
{'ball_1': <__main__.Ball object at 0x106f81048>, 'ball_2': <__main__.Ball object at 0x106f81080>}

Questions:

  1. Why does python behave this way?
  2. How can I make the str string appear in the list and the dictionary?
like image 992
Sahand Avatar asked Sep 25 '17 13:09

Sahand


1 Answers

print uses the __str__ method, but printing a dict or list invokes dict.__str__/list.__str__ respectively, which use the __repr__ method to serialise contained items. Define __repr__ on your class to mimic __str__. E.g. this will do:

class Ball:
    ...

    def __str__(self):
        ...

    __repr__ = __str__

Note that __repr__ should return a representation which preferably is valid Python code, like Ball(Board(100, 100, 2)).

like image 132
deceze Avatar answered Oct 16 '22 01:10

deceze