El método __str__ no funciona cuando los objetos están dentro de una lista o dict.

En este ejemplo, la primera statement de impresión genera la cadena devuelta por ball.__str__() , mientras que las otras dos no:

 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) 

salida:

 Ball: x=50, y=50, r=100, vx=0, vy=0 [, ] {'ball_1': , 'ball_2': } 

Preguntas:

  1. ¿Por qué se comporta Python de esta manera?
  2. ¿Cómo puedo hacer que la cadena de caracteres aparezca en la lista y en el diccionario?

print utiliza el método __str__ , pero la impresión de un dict o list invoca dict.__str__ / list.__str__ respectivamente, que utiliza el método __repr__ para serializar los elementos contenidos. Define __repr__ en tu clase para imitar a __str__ . Por ejemplo, esto hará:

 class Ball: ... def __str__(self): ... __repr__ = __str__ 

Tenga en cuenta que __repr__ debe devolver una representación que preferiblemente sea un código Python válido, como Ball(Board(100, 100, 2)) .

Un ejemplo debería ayudar.

 class Foo(): def __str__(self): return '__str__' def __repr__(self): return '__repr__' x = Foo(); print(x) __str__ lst = [Foo(), Foo(), Foo()] print(lst) [__repr__, __repr__, __repr__] 

Dentro de una estructura de datos, se __repr__ método __repr__ , no al __str__ . Si no tiene ninguno de estos métodos definidos, python __repr__ al __repr__ predeterminado que proporciona el object .

Como se mencionó, la solución es definir un método __repr__ y hacer que se refiera al método __str__ actualmente definido de su clase.

También puedes simular el método después de la definición de la clase, de esta manera:

 Foo.__repr__ = Foo.__str__