Python’s Object Model Objects by Design http://www.aleax.it/Python/nylug05_om.pdf ©2005 Alex Martelli [email protected] What’s OOP? I dunno -- what’s OOP with you? Alley Oop...? 2 INTRODUCTION Alley Oop made his official "big time" debut in the nation's funny pages on August 7, 1933. Not surprisingly, Alley found himself in a jam in the very first panel—lost in the jungles of Moo and surrounded by hungry dinosaurs. Within a week of his initial appearance he had stumbled upon Dinny, the dinosaur who quickly became his pet and principal means of transportation while in Moo. Soon after, he made his way out of the jungle and met up with King Guz and his rhyming friend, Foozy. Along the way he met his new girlfriend, Ooola, and the King's advisor, the Grand Wizer. Later in his career, Alley Oop was plucked from the Land of Moo by Dr. Wonmug's time machine. Dr. Wonmug brought Alley and Ooola to the 20th century, where a new series of Three faces of OOP OOP : package state and behavior into suitable “chunks”, in order to achieve...: Delegation let something else do (most of) the work Polymorphism act “as if” you were something else Instantiation one “blueprint”, many instances 3 OOP for delegation intrinsic/implicit (via attribute lookup): instance -> class class -> descriptors class -> base classes overt/explicit: containment and delegation (hold/wrap) delegation to self inheritance: more rigid; IS-A... hold/wrap: more flexible; USES-A... 4 Attribute lookup x.y [and identically x.y()!] means: check out descriptor stuff or else try x.__dict__['y'] or else try type(x).__dict__['y'] or else try: for base in type(x).__mro__: ... x.y = z means: check out descriptor stuff or else x.__dict__['y'] = z 5 Descriptors the key infrastructure of Python's OOP attribute access (get, set, delete) -> search class/superclasses dicts for name if suitable descriptor found, delegate all descriptors have method __get__ if also has , data descriptor (aka __set__ override descriptor) meaning: class overrides instance otherwise, non-data/non-override desc. 6 Descriptor mechanics (r) x = C(); return x.foo ==> if hasattr(C, 'foo'): d = C.foo; D = d.__class__ if hasattr(D, '__get__') \ and (hasattr(D, '__set__') or 'foo' not in x.__dict__): return D.__get__(d, x, C) return x.__dict__['foo'] # or from C, &c 7 Descriptor mechanics (w) x = C(); x.foo = 23 ==> if hasattr(C, 'foo'): d = C.foo; D = d.__class__ if hasattr(D, '__set__'): D.__set__(d, x, 23) return x.__dict__['foo'] = 23 8 Functions are descriptors def adder(x, y): return x + y add23 = adder.__get__(23) add42 = adder.__get__(42) print add23(100), add42(1000) 123 1042 9 built-in type property property(fget=None, fset=None, fdel=None, doc=None) # fget(obj) -> value # fset(obj, value) # fdel(obj) class Foo(object): def getBar(self): return 23 def setBar(self, val): pass def delBar(self): pass bar = property(getBar, setBar, delBar, "barbarian rhubarb baritone") 10
Description: