By Amarjit Singh Karanvir Singh - University Of Colorado .

Transcription

Object Oriented Programming in PythonBy Amarjit SinghKaranvir Singh*#%? %

Contents2Part 1Object Oriented Programming BasicsPart 2Object Oriented Programming in PythonPart 3Design Patterns & PythonPart 4More about PythonBasic Concepts of Object Oriented ProgrammingHow to do Object Oriented Programming in PythonHow to implement design pattern in PythonMore information about the language

Object Oriented Programming Concepts3

Object Oriented Programming BasicsProgramming ParadigmsBefore diving deep into theconcept of Object OrientedProgramming, let’s talk alittle about all theprogramming paradigmswhich exist in this world.ProceduralObjectural Modules, data structures and procedures thatoperate upon them Objects which encapsulate state and behavior andmessages passed between theses objects Functions and closures, recursion, lists, Functional4

Object Oriented Programming BasicsProgramming ParadigmsPython is multiparadigmprogramming languageIt allows the programmer to choose the paradigmthat best suits the problemIt allows the program to mix paradigmsIt allows the program to evolve switching paradigmif necessary5

Object Oriented Programming BasicsWhat is an Object?A software item thatcontains variables andmethods.Encapsulation dividing the code into a public interface, and aprivate implementation of that interfaceObject Oriented Designfocuses on :PolymorphismInheritance6 the ability to overload standard operators so thatthey have appropriate behavior based on theircontext the ability to create subclasses that containspecializations of their parents

Object Oriented Programming BasicsWhat is a Class?Classes(in classic oo) definewhat is common for a wholeclass of objects, e.g.:“Snowy is a dog” can betranslated to “The Snowyobject is an instance of thedog class.” Define once howa dog works and then reuseit for all dogs. Classescorrespond to variabletypes( they are typeobjects).At the simplest level, classesare simply namespaces.7DogSnowy

Object Oriented Programming in PythonI have class8

Object Oriented Programming in PythonPython Classes 9A class is a python object with several characteristics:You can call a class as it where a function and this call returns a newinstance of the classA class has arbitrary named attributes that can be bound, unbound anreferencedThe class attributes can be descriptors (including functions) or normal dataobjectsClass attributes bound to functions are also known as methodsA method can have special python-defined meaning (they’re named withtwo leading and trailing underscores)A class can inherit from other classes, meaning it delegates to other classesthe look-up of attributes that are not found in the class itself

Object Oriented Programming in PythonPython Classes in Detail (I) All classes are derived from object (new-style classes).class Dog(object):pass Python objects have data and function attributes (methods)class Dog(object):def bark(self):print "Wuff!“snowy Dog()snowy.bark() # first argument (self) is bound to this Dog instancesnowy.a 1 # added attribute a to snowy10

Object Oriented Programming in PythonPython Classes in Detail (II) Always define your data attributes in initclass Dataset(object):def init (self):self.data Nonedef store data(self, raw data):. # process the dataself.data processed data Class attributes are shared across all instances.class Platypus(Mammal):latin name "Ornithorhynchus anatinus"11

Object Oriented Programming in PythonPython Classes in Detail (III) Use super to call a method from a superclass.class Dataset(object):def init (self, data None):self.data dataclass MRIDataset(Dataset):def init (self, data None, parameters None):# here has the same effect as calling# Dataset. init (self)super(MRIDataset, self). init (data)self.parameters parametersmri data MRIDataset(data [1,2,3])12

Object Oriented Programming in PythonPython Classes in Detail (IV)Special methods start and end with two underscores and customizestandard Python behavior (e.g. operator overloading). class My2Vector(object):def init (self, x, y):self.x xself.y ydef add (self, other):return My2Vector(self.x other.x, self.y other.y)v1 My2Vector(1, 2)v2 My2Vector(3, 2)v3 v1 v213

Object Oriented Programming in PythonPython Classes in Detail (V) Properties allow you to add behavior to data attributes:class My2Vector(object):def init (self, x, y):self. x xself. y ydef get x(self):return self. xdef set x(self, x):self. x xx property(get x, set x)# define getter using decorator syntax@propertydef y(self):return self. yv1 My2Vector(1, 2)x v1.x # use the getterv1.x 4 # use the setterx v1.y # use the getter14

Object Oriented Programming in PythonPython Example (I)import randomclass Die(object): # derive from object for new style classes"""Simulate a generic die.""“def init (self, sides 6):"""Initialize and roll the die.sides -- Number of faces, with values starting at one(default is 6)."""self. sides sides # leading underscore signals privateself. value None # value from last rollself.roll()def roll(self):"""Roll the die and return the result."""self. value 1 random.randrange(self. sides)return self. value15

Object Oriented Programming in PythonPython Example (II)def str (self):"""Return string with a nice description of the die state."""return "Die with %d sides, current value is %d." %(self. sides, self. value)class WinnerDie(Die):"""Special die class that is more likely to return a 1."""def roll(self):"""Roll the die and return the result."""super(WinnerDie, self).roll() # use super instead ofDie.roll(self)if self. value 1:return self. valueelse:return super(WinnerDie, self).roll()16

Object Oriented Programming in PythonPython Example (III) die Die() die. sides # we should not access this, but nobody will stop us6 die.roll bound method Die.roll of dice.Die object at 0x03AE3F70 for in range(10):.print die.roll()2265212632 print die # this calls strDie with 6 sides, current value is 2. winner die dice.WinnerDie() for in range(10):.print winner die.roll(),2211421551 17

Design Patterns & PythonNotbad!18

Design Patterns & PythonWhat is a Design Pattern?Design Patterns are concretesolutions for reoccurringproblems.They satisfy the designprinciples and can be usedto understand and illustratethem.They provide a NAME tocommunicate effectivelywith other yPatternAdapterPattern19 The essence of the Iterator Factory method Pattern isto "Provide a way to access the elements of anaggregate object sequentially without exposing itsunderlying representation.". The decorator pattern is a design pattern that allowsbehavior to be added to an existing objectdynamically. The strategy pattern (also known as the policypattern) is a particular software design pattern,whereby algorithms behavior can be selected atruntime. The adapter pattern is a design pattern that translatesone interface for a class into a compatible interface

Iterator Pattern20

Iterator PatternProblem How would you iterate elements from a collection? my collection ['a', 'b', 'c'] for i in range(len(my collection)):.print my collection[i],abc But what if my collection does not support indexing? my collection {'a': 1, 'b': 2, 'c': 3} for i in range(len(my collection)):.print my collection[i],# What will happen here? 21This violates one of the design principles!

Iterator PatternDescription22 store the elements in a collection (iterable) manage the iteration over the elements by means of an iteratorobject which keeps track of the elements which were alreadydelivered iterator has a next() method that returns an item from the collection. When all items have been returned it raises a Stop Iteration exception. iterable provides an iter () method, which returns an iteratorobject.

Iterator PatternExample (I)class MyIterable(object):"""Example iterable that wraps a sequence."""def init (self, items):"""Store the provided sequence of items."""self.items itemsdef iter (self):return MyIterator(self)class MyIterator(object):"""Example iterator that is used by MyIterable."""def init (self, my iterable):"""Initialize the iterator.my iterable -- Instance of MyIterable."""self. my iterable my iterableself. position 023

Iterator PatternExample (II)def next(self):if self. position len(self. my iterable.items):value self. my iterable.items[self. position]self. position 1return valueelse:raise StopIteration()# in Python iterators also support iter by returning selfdef iter (self):return self24

Iterator PatternExample (III) First, lets perform the iteration manually:iterable MyIterable([1,2,3])iterator iter(iterable) # or use iterable. iter ()try:while True:item iterator.next()print itemexcept StopIteration:passprint "Iteration done." A more elegant solution is to use the Python for-loop:for item in iterable:print itemprint "Iteration done." In fact Python lists are already iterables:for item in [1,2,3]:print item25

Decorator Pattern26

Decorator PatternProblem (I)class Beverage(object):# imagine some attributes like temperature, amount left,.def get description(self):return "beverage“def get cost(self):return 0.00class Coffee(Beverage):def get description(self):return "normal coffee"def get cost(self):return 3.00class Tee(Beverage):def get description(self):return "tee"def get cost(self):return 2.5027

Decorator PatternProblem (II)class CoffeeWithMilk(Coffee):def get description(self):return super(CoffeeWithMilk, self).get description() ", with milk“def get cost(self):return super(CoffeeWithMilk, self).get cost() 0.30class CoffeeWithMilkAndSugar(CoffeeWithMilk):# And so on, what a mess!28

Decorator PatternDescriptionWe have the following requirements: adding new ingredients like soy milk should be easy and workwith all beverages, anybody should be able to add new custom ingredientswithout touching the original code (open-closed principle), there should be no limit to the number of ingredients.Use theDecoratorPattern heredude!29

Decorator PatternSolutionclass Beverage(object):def get description(self):return "beverage“def get cost(self):return 0.00class Coffee(Beverage):#[.]class BeverageDecorator(Beverage):def init (self, beverage):super(BeverageDecorator, self). init () # not really needed hereself.beverage beverageclass Milk(BeverageDecorator):def get description(self):#[.]def get cost(self):#[.]coffee with milk Milk(Coffee())30

Strategy Pattern31

Strategy PatternProblemclass Duck(object):def init (self):# for simplicity this example class is statelessdef quack(self):print "Quack!“def display(self):print "Boring looking duck.“def take off(self):print "I'm running fast, flapping with my wings.“def fly to(self, destination):print "Now flying to %s." % destinationdef land(self):print "Slowing down, extending legs, touch down."32

Strategy PatternProblem (I)class RedheadDuck(Duck):def display(self):print "Duck with a read head.“class RubberDuck(Duck):def quack(self):print "Squeak!“def display(self):print "Small yellow rubber duck." 33Oh man! The RubberDuck is able to fly!Looks like we have to override all the flying related methods.But if we want to introduce a DecoyDuck as well we will have to override allthree methods again in the same way (DRY).And what if a normal duck suffers a broken wing?Idea: Create a FlyingBehavior class which can be plugged into theDuckclass.

Strategy PatternSolution (I)class FlyingBehavior(object):"""Default flying behavior."""def take off(self):print "I'm running fast, flapping with my wings."def fly to(self, destination):print "Now flying to %s." % destinationdef land(self):print "Slowing down, extending legs, touch down.“class Duck(object):def init (self):self.flying behavior FlyingBehavior()def quack(self):print "Quack!"def display(self):print "Boring looking duck."def take off(self):self.flying behavior.take off()def fly to(self, destination):self.flying behavior.fly to(destination)def land(self):self.flying behavior.land()34

Strategy PatternSolution (II)class r for ducks that are unable to fly."""def take off(self):print "It's not working :-("def fly to(self, destination):raise Exception("I'm not flying anywhere.")def land(self):print "That won't be necessary.“class RubberDuck(Duck):def init (self):self.flying behavior NonFlyingBehavior()def quack(self):print "Squeak!"def display(self):print "Small yellow rubber duck.“class DecoyDuck(Duck):def init (self):self.flying behavior NonFlyingBehavior()def quack(self):print ""def display(self):print "Looks almost like a real duck."35

Adapter Pattern36

Adapter PatternProblem Lets say we obtained the following class from our collaborator:class Turkey(object):def fly to(self):print "I believe I can fly.“def gobble(self, n):print "gobble " * nHow to integrate it with our Duck Simulator: turkeys can fly and gobblebut they can not quack!37

Adapter PatternDescription38

Adapter PatternSolutionclass TurkeyAdapter(object):def init (self, turkey):self.turkey turkeyself.fly to turkey.fly to #delegate to native Turkey methodself.gobble count 3def quack(self): #adapt gobble to quackself.turkey.gobble(self.gobble count) turkey Turkey() turkeyduck TurkeyAdapter(turkey) turkeyduck.fly to()I believe I can fly. turkeyduck.quack()gobble gobble gobbleAdapter Pattern applies several good design principles: uses composition to wrap the adaptee (Turkey) with an altered interface, binds the client to an interface not to an implementation39

More About Python40

More About PythonObject modelsSince Python2.2 there co-exist two slightly dierent object models inthe languageOld-style (classic) classes : This is the model existing prior toPython2.2New-style classes :This is the preferred model for new codeOld Style class A: pass class B: pass a, b A(), B() type(a) type(b)True type(a) type 'instance' 41New Style class A(object): pass class B(object): pass a, b A(), B() type(a) type(b)False type(a) class ' main .A'

More About PythonNew-style classes Defined in the type and class unification effort in python2.2(Introduced without breaking backwards compatibility)Simpler, more regular and more powerful It will be the default (and unique) in the futureDocuments: 42Built-in types (e.g. dict) can be subclassedProperties: attributes managed by get/set methodsStatic and class methods (via descriptor API)Cooperative classes (sane multiple inheritance)Meta-class programmingUnifying types and classes in Python 2.2PEP-252: Making types look more like classesPEP-253: Subtyping built-in types

More About PythonThe class statementclass classname(base-classes):statement(s) classname is a variable that gets (re)bound to the class object after theclass statement finishes executingbase-classes is a comma separated series of expressions whose values mustbe classes 43if it does not exists, the created class is old-styleif all base-classes are old-style, the created class is old-styleotherwise it is a new-style class1since every type subclasses built-in object, we can use object tomark a class as new-style when no true bases existThe statements (a.k.a. the class body) dene the set of class attributes whichwill be shared by all instances of the class

More About PythonClass-private attributes When a statement in the body (or in a method in the body) uses anidentifier starting with two underscores (but not ending with them) such asprivate, the Python compiler changes it to classname private This lets classes to use private names reducing the risk of accidentallyduplicating names used elsewhere By convention all identifiers starting with a single underscore are meant to be private in the scope that binds them class C5(object):. private 23 print C5. privateAttributeError: class A has no attribute ' private' print C5. C5 private2344

More About PythonDescriptors45 A descriptor is any new-style object whose class supplies a special methodnamed get Descriptors that are class attributes control the semantics of accessing andsetting attributes on instances of that class If a descriptor's class also supplies method set then it is called anoverriding descriptor (a.k.a. data descriptor) If not, it is called non-overriding (a.k.a. non-data) descriptor Function objects (and methods) are non-overriding descriptors Descriptors are the mechanism behind properties, methods, staticmethods, class methods, and super (cooperative super-classes) The descriptor protocol also contains method delete for unbindingattributes but it is seldom used

Thank You46

A class is a python object with several characteristics: You can call a class as it where a function and this call returns a new instance of the class A class has arbitrary named attributes that can be bound, unbound an referenced The class attributes can be descriptors (including functions) or normal data objects