inheritance - Subclassing in python of instantiated superclass -
is possible subclass in python using instantiated superclass?
i don't know how frame question let me give example. suppose have class rectangle , want build class coloredrectangle. don't want each coloredrectangle of same dimensions own new rectangle. when initiate coloredrectangle pass instantiated rectangle.
ie., want
r = rectangle([1,2]) r_red = coloredrectangle(r, "red") r_blue = coloredrectangle(r, "blue") but r_red , r_blue should able rectangle methods , attributes. example suppose rectangle had area() attribute.
r.area 2 r_red.area 2 r_red , r_blue should "point" same rectangle. know writing:
class coloredrectangle(rectangle): def __init__(self, rectangle, color): self.color = color self.rectangle = rectangle but i'd have write
r_red.rectangle.area which ugly.
inheritance
inheritance such nice thing in python, , don't think have resort getattr hacks, if want those, scroll down.
you can force class dictionary refer object:
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 these 2 refer same rectangle object:
crect.width=10 print rect.width, rect.height #10 5 this exellent talk on metaprogramming, , while it's title implies python3 lot of applies python 2.x: david beazley - python3 metaprogramming
getattr hacking
if reason however, want have multiple coloredrectangle refer same base rectangle these conflict each other:
eve = rectangle(3, 5) kain = coloredrectangle(eve, color="blue") abel = coloredrectangle(eve, color="red") print eve.color, kain.color, abel.color #red red red if you'd different "proxy objects", can attributes base rectangle not interfere each other, have resort getattr hacking, fun too:
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) this avoid interference:
kain = coloredrectangle(eve, color="blue") abel = coloredrectangle(eve, color="red") print kain.color, abel.color #blue red about __getattr__ versus __getattribute__:
a key difference between getattr , getattribute getattr invoked if attribute wasn't found usual ways. it's implementing fallback missing attributes, , 1 of 2 want. source
because non found attributes handled __getattr__ can partially update proxies, might confusing:
kain.width=10 print eve.area(), kain.area(), abel.area() # 15 50 15 to avoid can override __setattr__:
def __setattr__(self, attr, value): if attr == "color": return super(coloredrectangle,self).setattr(attr,value) raise yourfavoriteexception
Comments
Post a Comment