Python & Perl: Lecture 16

  • 595 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
595
On Slideshare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
0
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Python & Perl Lecture 16 Vladimir Kulyukin Department of Computer Science Utah State Universitywww.youtube.com/vkedco www.vkedco.blogspot.com
  • 2. Outline ● Magic Methods ● Superclass Constructors ● Protocols ● Python Sequence Protocolwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 3. Magic Methodswww.youtube.com/vkedco www.vkedco.blogspot.com
  • 4. Magic Methods ● Magic methods in Python start and end with double underscores __ ● Magic methods are called by Python under specific circumstances: – __init__() - called when objects are constructed – __eq__() - called when objects are comparedwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 5. Magic Method __init__() ● When a class defines __init__(), it is called when instances of that class are constructed ## __init__ with no ## __init__ with one argument ## arguments class A2: class A1: def __init__(self, x=10): def __init__(self): self.x = x self.x = 10www.youtube.com/vkedco www.vkedco.blogspot.com
  • 6. Magic Method __del__() ● When a class defines __del__(), it is called when instances of that class are destroyed by the garbage collector SOURCE OUTPUT class A3: >>> a = A3(x=200) def __init__(self, x=10): >>> del a self.my_list = [i for i in xrange(x)] Destroying an A3 object def __del__(self): print Destroying an A3 object del self.my_listwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 7. Overriding __init__() ● Magic method __init__() can be overriden ● When a class A overrides __init__() and its superclasses contain attributes that A objects use, As __init__() must call explicitly its superclass constructors ● If As __init__() does not call superclass constructors, run-time attribute access errors are likelywww.youtube.com/vkedco www.vkedco.blogspot.com
  • 8. Example SOURCE OUTPUT __metaclass__ = type >>> p1 = TwoDPoint(10, 10) import math >>> p2 = ThreeDPoint(30) class TwoDPoint: >>> p2.x def __init__(this, x=0, y=0): AttributeError: ThreeDPoint object has no attribute x this.x = x >>> p2.y this.y = y AttributeError: ThreeDPoint object has no def distance_from_origin(this): attribute y return math.hypot(this.x, this.y) class ThreeDPoint(TwoDPoint): def __init__(this, z=0): this.z = zwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 9. Fixing Attribute Construction Problem ● ThreeDPoint inherits from TwoDPoint ● However, as the examples output shows, ThreeDPoint objects do not have the attributes x and y ● The problem can be fixed by having ThreeDPoints constructor explicitly call the constructor of its superclass ● There are two ways of calling superclass constructors: – Unbound superclass constructor – The function super()www.youtube.com/vkedco www.vkedco.blogspot.com
  • 10. Calling Superclass Constructorswww.youtube.com/vkedco www.vkedco.blogspot.com
  • 11. Calling Unbound Superclass Constructor SuperClass.__init__(self, arguments) – Superclassis the superclass of selfs class – arguments are the arguments to SuperClasss constructorwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 12. Example SOURCE OUTPUT __metaclass__ = type >>> p = ThreeDPoint(10, 20, 30) import math >>> p.x class TwoDPoint: 10 def __init__(this, x=0, y=0): >>> p.y this.x = x 20 this.y = y >>> p.z def distance_from_origin(this): 30 return math.hypot(this.x, this.y) class ThreeDPoint(TwoDPoint): def __init__(this, x=0, y=0, z=0): TwoDPoint.__init__(this, x, y) this.z = zwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 13. Dealing with Multiple Inheritance ● An appropriate unbound superclass constructor must be called for every inherited attribute ● If class A inherits attribute x from class B and attribute y from class C, As constructor must call both constructors to ensure that both attributes are constructedwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 14. Example SOURCE OUTPUT class A: >>> c = C(10, 20, 30) def __init__(this, x=0): >>> c.x this.x = x 10 class B: >>> c.y def __init__(this, y=0): 20 this.y = y >>> c.z class C(A, B): 30 def __init__(this, x=0, y=0, z=0): A.__init__(this, x) B.__init__(this, y) this.z = zwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 15. Calling Function super() super(Class, self).__init__(arguments) – Class is the class of self object – super(Class, self) returns the object of Classs superclass – arguments are the arguments to the __init__ method of Classs superclasswww.youtube.com/vkedco www.vkedco.blogspot.com
  • 16. Example SOURCE OUTPUT class TwoDPoint: >>> p = ThreeDPoint(10, 20, 30) def __init__(this, x=0, y=0): >>> p.x this.x = x 10 this.y = y >>> p.y def dist_from_origin(this): 20 math.hypot(this.x, this.y) >>> p.z 30 class ThreeDPoint(TwoDPoint): def __init__(this, x=0, y=0, z=0): super(ThreeDPoint, this).__init__(x, y) this.z = zwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 17. Protocolswww.youtube.com/vkedco www.vkedco.blogspot.com
  • 18. Protocols ● In CS, the term protocol is typically used to describe a set of rules that govern a specific behavior ● In Python, a protocol specifies a set of methods and what they should do and when ● In Python, protocols are a consequence of duck typing: an objects behavior is not based on its class but on what methods can apply to itwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 19. Example: Sequence Protocol ● Sequences are collections of items ● An object implements the sequence protocol if it supports the following methods: – __len__(self): return number of items in self , called when len(self) is called – __getitem__(self, key): called when self[key] is evaluated – __setitem__(self, key, value): called when self[key] = value is evaluated – __delitem__(self, key): called when del self[key] is evaluatedwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 20. Example ● Implement class PixSeq that supports the sequence protocol for PIL RGB images >>> ps = PixSeq(10, 10) ## creates 10x10 image >>> ps[21] ## returns RGB pixel 21, calls __getitem__() >>> len(ps) ## returns 100, calls __len__() >>> ps[21] = (25, 30, 234) ## sets pixel 21 to (25, 30, 234) ## calls __setitem__() >>> del ps[21] ## deletes pixel 21, calls __delitem__www.youtube.com/vkedco www.vkedco.blogspot.com
  • 21. Examples Source Code http://vkedco.blogspot.com/2012/03/python-perl-pil-images-as-mutable.htmlwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 22. PixSeq: Construction & Destruction class PixSeq: ## x - width, y - height def __init__(self, x=0, y=0): self.__img = Image.new(RGB, (x, y), (0, 0, 0)) ## __delPix is a dictionary of deleted pixels self.__delPix = {} def __del__(self): del self.__imgwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 23. PixSeq: (Semi)Private Support Functions ## key is valid if it is int or long and ## is in the range [0, length-1], where ## length = x * y = __img.size[0]*__img.size[1]-1. def __isValidKey(self, key): if not isinstance(key, (int, long)): raise TypeError elif key < 0 or key > self.__img.size[0] * self.__img.size[1] - 1: raise IndexError else: return Truewww.youtube.com/vkedco www.vkedco.blogspot.com
  • 24. PixSeq: (Semi)Private Support Functions ## value is valid if it is a tuple with three elements ## each of which is in the range [0, 255] def __isValidValue(self, value): if not isinstance(value, tuple): raise TypeError elif len(value) != 3: raise ValueError else: v1, v2, v3 = value if v1 < 0 or v1 > 255: raise ValueError elif v2 < 0 or v2 > 255: raise ValueError elif v3 < 0 or v3 > 255: raise ValueError else: return Truewww.youtube.com/vkedco www.vkedco.blogspot.com
  • 25. PixSeq: (Semi)Private Support Functions ● Since we are in PIL, x is horizontal dimension, y is vertical dimension ● One-dimensional pixel access formula is y * width + x = key ● Given key and width, x = key % width; y = (key – x)/width ● Suppose we have a 5 x 3 image (x = 5, y = 3), then width=5 – Suppose key = 2, then x = 2 % 5 = 2 and y = (2 - 2)/5 = 0 – Suppose key = 7, then x = 7 % 5 = 2 and y = (7 – 2)/5 = 1www.youtube.com/vkedco www.vkedco.blogspot.com
  • 26. PixSeq: (Semi)Private Support Functions ## given key return its x, y PIL coords def __pixCoords(self, key): width = self.__img.size[0] x = key % width y = (key - x)/width return (x, y)www.youtube.com/vkedco www.vkedco.blogspot.com
  • 27. PixSeq: Magic Methods of Sequence Protocol def __len__(self): x, y = self.__img.size return x * y def __getitem__(self, key): try: self.__isValidKey(key) except (TypeError, IndexError), ex: raise ex else: if not self.__delPix.has_key(key): return self.__img.getpixel(self.__pixCoords(key)) else: raise KeyErrorwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 28. PixSeq: Magic Methods of Sequence Protocol def __setitem__(self, key, value): try: self.__isValidValue(value) except (TypeError, IndexError), ex: raise ex else: ## get the x,y coords from key pix_coords = self.__pixCoords(key) if self.__delPix.has_key(key): ## if key has been deleted, reinstate it del self.__delPix[key] self.__img.putpixel(pix_coords, value) else: self.__img.putpixel(pix_coords, value)www.youtube.com/vkedco www.vkedco.blogspot.com
  • 29. PixSeq: Magic Methods of Sequence Protocol def __delitem__(self, key): try: self.__isValidKey(key) except (TypeError, IndexError), ex: raise ex else: self.__delPix[key] = Truewww.youtube.com/vkedco www.vkedco.blogspot.com
  • 30. Feedback Bugs, comments to vladimir dot kulyukin at usu dot eduwww.youtube.com/vkedco www.vkedco.blogspot.com
  • 31. Reading & References ● www.python.org ● http://en.wikipedia.org/wiki/Duck_typing ● http://www.pythonware.com ● Ch 09 M. L. Hetland. Beginning Python From Novice to Pro- nd fessional, 2 Ed., APRESSwww.youtube.com/vkedco www.vkedco.blogspot.com