Странное поведение __str__ при композиции классов
При попытке вызова метода __str__ у класса Robot должны сработать __str__ у его вложенных классов Laser, Claw и SmartPhone. Однако, при выводе вместо ожидаемого:
Laser disintegrate
Claw crush
Smart Phone ring
Получается следующее:
Laser (<main.Laser object at 0x7fb2885f1fa0>,)
Claw (<main.Claw object at 0x7fb288617d90>,)
Smart Phone: ring
Корректное значение при выводе зависит от порядка инициализации в конструкторе класса Robot, т.е. кто последний инициализирован, у того __str__ отработает нормально.
В чем может быть причина подобного поведения?
class Base:
def __init__(self, value):
self.value = value
def does(self):
return self.value
def __str__(self):
return self.value
class Laser(Base):
def __init__(self, name):
super().__init__(name)
class Claw(Base):
def __init__(self, name):
super().__init__(name)
class SmartPhone(Base):
def __init__(self, name):
super().__init__(name)
class Robot:
def __init__(self, laser, claw, smart_phone):
self.laser = Laser(laser),
self.claw = Claw(claw),
self.smart_phone = SmartPhone(smart_phone)
def __str__(self):
return f"Laser {self.laser}\nClaw {self.claw}\nSmart Phone: {self.smart_phone}"
values = ['disintegrate', 'crush', 'ring']
robot = Robot(*values)
print(robot)
Ответы (1 шт):
Причина такого поведения в запятых в конце следуюших строк, которые превращают соответствующие переменные в кортежи (tuple):
self.laser = Laser(laser),
self.claw = Claw(claw),
уберите их и все заработает правильно:
In [93]: class Robot:
...: def __init__(self, laser, claw, smart_phone):
...: self.laser = Laser(laser)
...: self.claw = Claw(claw)
...: self.smart_phone = SmartPhone(smart_phone)
...:
...: def __str__(self):
...: return f"Laser {self.laser}\nClaw {self.claw}\nSmart Phone: {self.smart_phone}"
...:
In [94]: robot = Robot(*values)
In [95]: print(robot)
Laser disintegrate
Claw crush
Smart Phone: ring
PS если присвоить переменной какое-нибудь значение и поставить после этого значения запятую, то в переменную попадет кортеж (tuple), первым элементом которого будет указанное до запятой значение.
Пример:
In [86]: a = 1,
In [87]: type(a)
Out[87]: tuple
In [88]: print(a)
(1,)