这个问题与this非常相似,但我的派生类有额外的数据成员。考虑下面的两个类。我需要将Circle
个对象的实例转换为ColoredCircle
的实例。在我真实的,不太简单的应用程序中,我宁愿避免重新初始化数千个这些对象,确保我使用基本实例成员和诸如此类的东西正确调用派生类构造函数。
class Circle(object):
def __init__(self, radius):
self.radius = radius
def area(self):
return pi * self.radius**2
def __str__(self):
return 'Circle: %f' % self.radius
class ColoredCircle(Circle):
def __init__(self, radius, color):
super(ColoredCircle, self).__init__(radius)
self.color = color
def __str__(self):
return 'ColoredCircle: %f %s' % (self.radius, self.color)
def getColor(self):
return self.color
如果我有一个Circle
实例c
,我可以将其__class__
更改为ColoredCircle
,一旦我也设置了c.color
,那么一切似乎都起作用,好像我已经用ColoredCircle
开始实例化了。
问题:
c = Circle(3)
print c # Circle: 3.000000
print c.area() # 28.274333882308138
c.__class__ = ColoredCircle
print c.area() # still works
print c.getColor() # AttributeError: 'ColoredCircle' object has no attribute 'color'
c.color = 'blue'
print c # ColoredCircle: 3.000000 blue
答案 0 :(得分:3)
(1)是否存在任何重大缺陷或其他原因,如果将基类的实例强制转换为派生类的实例,则执行以下操作会是一个坏主意?
这是一个肮脏的脏兮兮的黑客,并侵犯了这个世界上所有善良和神圣的东西。小猫将在群众中灭亡。
这是对封装的公然违反。它只适用于派生类的深入了解。当你可以使用构造函数轻松创建一个干净的对象时,为什么要以脏的方式重写对象的DNA。
如果您完全了解目标对象的所有细节100%,那么确定,这是有效的,但这是一个非常脏的黑客。如果这是一次性校正或其他什么,你可能可以逃脱它,否则它将成为维护的噩梦,好像某天某些东西在目标类中发生了变化,你将不得不更新黑客。
(2)有更好的方法吗?
是的,使用构造函数创建不同类型的对象。现在还不清楚为什么你不愿意走这条明显的道路。