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