是否可以在Python中使用已经实例化的超类?
我不知道该如何构造这个问题,所以让我举个例子。假设我有一个矩形类,我想要构建另一个类ColoredRectangle。但我不希望每个相同维度的ColoredRectangle成为自己的新Rectangle。因此,当我启动ColoredRectangle时,我会传递给它一个已经实例化的Rectangle。
呃,我想
r = Rectangle([1,2])
r_red = ColoredRectangle(r, "red")
r_blue = ColoredRectangle(r, "blue")但是现在r_red和r_blue应该能够获得所有矩形方法和属性。例如,假设Rectangle有一个area()属性。
r.area
2
r_red.area
2r_red和r_blue应该“指向”同一个Rectangle。我知道我可以这样写:
 class ColoredRectangle(Rectangle):
      def __init__(self, rectangle, color):
          self.color = color
          self.rectangle = rectangle但那样我就得写
  r_red.rectangle.area这很难看。
发布于 2015-11-02 00:11:15
继承
继承在python中是一件很好的事情,我认为您不必求助于getattr黑客,如果需要,请向下滚动。
您可以强制类字典引用另一个对象:
class Rectangle(object):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def area(self):
        return self.width * self.height
class ColoredRectangle(Rectangle):
    def __init__(self, rect, color):
        self.__dict__ = rect.__dict__
        self.color = color
rect = Rectangle(3, 5)
crect = ColoredRectangle(rect, color="blue")
print crect.width, crect.height, crect.color
#3 5 blue这两个对象将引用同一个Rectangle对象:
crect.width=10
print rect.width, rect.height
#10 5这是关于元编程的精彩演讲,虽然它的标题暗示着Python3,但它也适用于python2.x:https://www.youtube.com/watch?v=sPiWg5jSoZI
getattr黑客
但是,如果出于任何原因,您希望多个ColoredRectangle引用相同的基本Rectangle,那么它们将相互冲突:
eve = Rectangle(3, 5)
kain = ColoredRectangle(eve, color="blue")
abel = ColoredRectangle(eve, color="red")
print eve.color, kain.color, abel.color
#red red red如果您想要不同的“代理对象”(可以从基本Rectangle获取属性,但不相互干扰),您可以使用求助于getattr黑客,这也很有趣:
class ColoredRectangle(Rectangle):
    def __init__(self, rect, color):
        self.rect = rect
        self.color = color
    def __getattr__(self,attr):
        return getattr(self.rect,attr)
eve = Rectangle(3, 5)这将避免下列干扰:
kain = ColoredRectangle(eve, color="blue")
abel = ColoredRectangle(eve, color="red")
print kain.color, abel.color
#blue red关于__getattr__与__getattribute__:
getattribute和getattr之间的一个关键区别是,只有在没有按照通常的方式找到属性时才调用getattr。它有利于实现丢失属性的回退,而且可能是您想要的两个属性中的一个。来源
由于只有未找到的属性将由__getattr__处理,所以您还可以部分更新代理,这可能会让人感到困惑:
kain.width=10
print eve.area(), kain.area(), abel.area()
# 15 50 15为了避免这种情况,您可以重写__setattr__
def __setattr__(self, attr, value):
    if attr == "color":
        return super(ColoredRectangle,self).setattr(attr,value)
    raise YourFavoriteExceptionhttps://stackoverflow.com/questions/33463232
复制相似问题