SlideShare a Scribd company logo
Topics in Advanced Python 
No agenda – jumping in... 
© 2014 Zaar Hai tech.zarmory.com
Decorators 
Decorator is a function that accepts a function and returns 
another function 
from functools import wraps 
def deco(f): 
@wraps(f) 
def wrapper(*args, **kwargs): 
print "started at %s" % time.time() 
rv = f(*args, **kwargs) 
print "finished at %s" % time.time() 
return wrapper 
@deco 
def sleeper(): 
"Sleeper function" 
time.sleep(2) 
>>> sleeper() 
started at 1384245972.01 
finished at 1384245974.01 
>>> print sleeper.__name__ 
sleeper 
wraps takes care about wrapped aux data. Without it: 
>>> print sleeper.__name__ 
wrapper 
Important when reading online help of someone else's code 
2 © 2014 Zaar Hai tech.zarmory.com
Decorator usage examples 
To return cached values 
To implement retries 
To guard methods/functions with a lock 
To validate input/output of the function 
To limit function execution by a certain timeout 
Decorators greatly help with code reuse and 
Make code explicitly readable 
3 © 2014 Zaar Hai tech.zarmory.com
Decorator is just a function 
You can call decorators “inline” in your code 
@deco 
def sleeper(): pass 
sleeper() 
deco(sleeper)() 
@deco1 
@deco2 
def sleeper(): pass 
sleeper() 
deco1(deco2((sleeper))() 
Similarly, decorators themselves can accept parameters 
@deco(5) 
def sleeper(): pass 
sleeper() 
deco(5)(sleeper)() 
Note: The invocation order is a bit different 
Note:@deco(5) is executed when the code is imported 
4 © 2014 Zaar Hai tech.zarmory.com
Decorator with parameter - example 
$ cat mydeco.py 
def deco(p): 
print "got %s" % p 
def real_deco(f): 
@wraps(f) 
def wrapper(*args, **kwargs): 
print "decorating" 
return f(*args, **kwargs) 
return wrapper 
return real_deco 
@deco(5) 
def hello(): pass 
>>> import mydeco # outer function runs during import 
got 5 
>>> mydeco.hello() # decorator runs when function executed 
decorating 
>>> 
5 © 2014 Zaar Hai tech.zarmory.com
Decorator can be a class 
Some times its useful to implement decorators as a class 
class deco(object): 
def __init__(self, p): 
self.p = p 
print "got %s" % p 
def __call__(self, f): 
@wraps(f) 
def wrapper(*args, **kwargs): 
print "decorating" 
return f(*args, **kwargs) 
return wrapper 
__call__ is a special method that is invoked when you try 
calling an object as if it was a function 
6 © 2014 Zaar Hai tech.zarmory.com
How does @property decorator work? 
@property – one of the most common decorators in Python 
class A(object): 
@property 
def a(self): 
return "a" 
>>> A().a 
'a' 
But how does it work? 
7 © 2014 Zaar Hai tech.zarmory.com
Meet descriptors 
Descriptor is a protocol for accessing object attributes 
class A(object): 
def __init__(self): 
self.a = 1 
>>> f = A(); f.a 
When you access a, what actually happens is 
v = self.__dict__["a"] 
if hasattr(v, '__get__'): 
return v.__get__(self) 
else: 
return v 
I.e. when attribute defines __get__ (or __set__) methods, 
they are called to produce (or set) actual attribute value 
8 © 2014 Zaar Hai tech.zarmory.com
Back to the @property 
@property implements both decorator and descriptor 
semantics like this: 
class Property(object): 
def __init__(self, getter): 
self.getter = getter 
def __get__(self, obj, csl): 
return self.getter(obj) 
class A(object): 
@Property 
def a(self): 
return "a" 
>>> o = A(); o.a 
'a' 
>>> type(o.a) 
<type 'str'> 
9 © 2014 Zaar Hai tech.zarmory.com
Descriptors in action 
One-time caching of method's return values 
class OneTime(object): 
def __init__(self, func): 
self.func = func 
def __get__(self, obj, cls): 
to_augment = obj or cls 
rv = self.func(to_augment) 
pname = self.func.__name__ 
setattr(to_augment, pname, rv) 
return rv 
class BigMath(object): 
@OneTime 
def big_data(self): 
print "working hard...." 
return 42 
Reusable – follows DRY principle 
More on this here and here 
class BigMath(object): 
def get_big_data(self): 
if hasattr(self, "_rv"): 
return self._rv 
self._rv = self._get_data() 
return self._rv 
def _get_data(self): 
print "working hard...." 
return 42 
Nice, but leads to a lot 
of copy/paste code 
10 © 2014 Zaar Hai tech.zarmory.com
© 2014 Zaar Hai tech.zarmory.com 
Multiple inheritance 
“LEGO” goes on
M-I in action - MixIns 
“MixIn” is a programming concept about creating aux class 
that enriches functionality of the main class 
class SteeringWheel(object): ... 
class HornMixIn(object): 
"""Mix-in class to enable horn functionality""" 
def horn(self, *args, **kwargs): 
print "move over!" 
class CruiseControlMixIn(object): 
def cc_set(self): … 
def cc_cancel(self): ... 
def cc_restore(self):... 
class Mazda2SteeringWheel(CruiseControlMixIn, HornMixIn, SteeringWheel): 
"""Sometimes there is nothing to configure here at all""" 
12 © 2014 Zaar Hai tech.zarmory.com
M-I in action – MixIns (continued) 
Here is another example 
class Synchronized(object): 
def __init__(self, *args, **kwargs): 
self._sync_lock = threading.Lock() 
super(Synchronized, self).__init__(*args, **kwargs) 
@staticmethod 
def synchronized(func): 
@wraps(func) 
def wrapper(self, *args, **kwargs): 
with self._sync_lock: 
return func(self, *args, **kwargs) 
return wrapper 
class Writer(Syncrhonized, Db): 
@Synchronized.synchronized 
def write(self, o): 
self.db.write(o) 
As we see, for a lot of real-live examples M-I can be used 
straight-forward and its behavior in Python “makes sense” 
13 © 2014 Zaar Hai tech.zarmory.com
“New style” classes 
Not exactly “new” - since Python 2.2 
Always inherit from object 
Really, Always inherit from object 
Use super to call ancestor methods 
class Foo(object): 
def bar(self): pass 
class Bar(Foo): 
def bar(self): 
return super(Bar, self).bar() 
class Foo: 
def bar(self): pass 
class Bar(Foo): 
def bar(self): 
return Foo.bar(self) 
Following the above technique will make your and others' life 
much easier 
14 © 2014 Zaar Hai tech.zarmory.com
Multiple inheritance and MRO 
class A(object): 
def __init__(self): 
super(A, self).__init__() 
print "A" 
class B(object): 
def __init__(self): 
super(B, self).__init__() 
print "B" 
class C(A,B): 
def __init__(self): 
super(C, self).__init__() 
print "C" 
What will be output of running C()? 
“A B C”? 
“B A C”? 
How do we arrive from super(A..) to the method of B? 
15 © 2014 Zaar Hai tech.zarmory.com
Multiple inheritance and MRO 
MRO – method resolution order 
Python utilizes C3 algorithm 
>>> C.__mro__ 
(<class 'my2.C'>, <class 'my2.A'>, <class 'my2.B'>, <type 'object'>) 
And the answer to the previous question is “B A C” 
For most real-life example I've seen, C3 logic “makes sense” 
Without inheriting from object and using super, one had to 
do MRO by himself in the code. 
Bottom line – super() does not return ancestor, but the next 
member of MRO chain 
16 © 2014 Zaar Hai tech.zarmory.com
MRO pitfalls 
class A(object): pass 
class B(object): pass 
class C(A,B): pass 
class D(B,A): pass 
class E(C,D): pass 
Where super(E, self).__init__() will end up? 
17 © 2014 Zaar Hai tech.zarmory.com
MRO pitfalls 
class A(object): pass 
class B(object): pass 
class C(A,B): pass 
class D(B,A): pass 
class E(C,D): pass 
Where super(E, self).__init__() will end up? 
>>> class E(C,D): pass 
... 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: Error when calling the metaclass bases 
Cannot create a consistent method resolution 
order (MRO) for bases B, A 
There are cases when C3 would (and should) fail to prevent a 
naive programmer from creating a mess 
18 © 2014 Zaar Hai tech.zarmory.com
type function revised 
All of you are familiar with type: 
>>> class A(object): pass 
>>> a = A() 
>>> type(a) 
<class '__main__.A'> 
BTW, don't use type(a) == A, but isinstance(a, A) 
What type(A) will print? 
19 © 2014 Zaar Hai tech.zarmory.com
type function revised 
>>> type(A) 
<type 'type'> 
In Python, object model hierarchy has two levels: 
Objects are instances of their Class 
Classes are instances of their Type – AKA metaclass 
All classes by default are instances of type metaclass, but we 
can define our own metaclasses of course: 
class MetaA(type): pass 
class A(object): 
__metaclass__ = MetaA 
>>> type(A) 
<class '__main__.MetaA'> 
Metaclass can augment class creation. More on this later 
20 © 2014 Zaar Hai tech.zarmory.com
Yet another face of type function 
type can be used to create new classes on the fly 
The syntax: type(name, bases, dict) 
class Actor(object): 
def get(self, req): 
return self.val 
for c in [Volumes, Hosts]: 
class Conf(object): pass 
class Volumes(Conf): 
url = '/volumes' 
val = 5 
class Hosts(Conf): 
url = '/hosts' 
val = 4 
HandlerClass = type('Handler', (Actor, c), {}) 
HttpServer.addUrl(c.url, HandlerClass) 
HttpServer.start() 
Allows really decoupled design. Yet flexible and efficient. 
21 © 2014 Zaar Hai tech.zarmory.com
Metaclass example – proper Enum 
class UserRoles(Enum): 
root = 10 
user = 20 
user__desc = "Regular users" 
Nobody = 30 
>>> UserRoles.root 
10 
>>> UserRoles.root.name 
'root' # Wow, I have a name! 
>>> UserRoles.user.desc 
'Regular users' # And even description 
>>> UserRoles.root == 10 
True # I look and quack just like the native type I was assigned to 
>>> role = UserRoles(10) # Cast me! (with the DB value for example) 
>>> role; role.name; role == 10 
10 
'root' 
True 
>>> role == UserRoles.root 
True 
Magic? May be; but a simple one 
22 © 2014 Zaar Hai tech.zarmory.com
Magic revealed 
class EnumMeta(type): 
def __new__(mcs, name, base, d): 
cls = super(EnumMeta, mcs).__new__(mcs, name, base, d) 
for k, v in cls.__dict__.items(): 
pname = getattr(cls, k+"__name", k) 
pdesc = getattr(cls, k+"__desc", "") 
n = type(v).__name__ 
prop = type(n, (type(v),), {"name" : pname, "desc" : pdesc}) 
p = prop(v) 
setattr(cls, k, p) 
return cls 
class Enum(object): 
__metaclass__ = EnumMeta 
Full story here 
23 © 2014 Zaar Hai tech.zarmory.com
© 2014 Zaar Hai tech.zarmory.com 
Thank you …

More Related Content

PPTX
Queue
Brigita Wensen
 
PDF
[RPL2] Class Diagram dan Relasinya (2)
rizki adam kurniawan
 
PDF
Object oriented approach in python programming
Srinivas Narasegouda
 
PDF
[PBO] Pertemuan 11 - GUI Java Desktop
rizki adam kurniawan
 
PPTX
C++ project
Sonu S S
 
PDF
Laporan Praktikum Algoritma
EnvaPya
 
PPTX
Pertemuan 1 Pemodelan Perangkat Lunak
Disma Ariyanti W
 
PDF
[PBO] Pertemuan 5 - Inheritance
rizki adam kurniawan
 
[RPL2] Class Diagram dan Relasinya (2)
rizki adam kurniawan
 
Object oriented approach in python programming
Srinivas Narasegouda
 
[PBO] Pertemuan 11 - GUI Java Desktop
rizki adam kurniawan
 
C++ project
Sonu S S
 
Laporan Praktikum Algoritma
EnvaPya
 
Pertemuan 1 Pemodelan Perangkat Lunak
Disma Ariyanti W
 
[PBO] Pertemuan 5 - Inheritance
rizki adam kurniawan
 

What's hot (20)

PPT
Java: Inheritance
Tareq Hasan
 
PDF
[PBO] Pertemuan 6 - Abstrak
rizki adam kurniawan
 
DOCX
MAC Address Table Management menggunakan Cisco Packet Tracer
Ryandika Alfarishi
 
PDF
Materi Augmented Reality
Fajar Baskoro
 
PDF
Queue
Sherly Uda
 
PDF
Pemrograman Mobile Unit 2 : Dasar-dasar Flutter
Akhmad Khanif Zyen
 
PPTX
WHAT IS ABSTRACTION IN JAVA
sivasundari6
 
PDF
Modul Praktikum Sistem Basis Data
Wahyu Widodo
 
PPT
Methods in C#
Prasanna Kumar SM
 
ODP
Best practices in Java
Mudit Gupta
 
PDF
7. Queue (Struktur Data)
Kelinci Coklat
 
PPTX
Pengantar robotika
Abdul Fauzan
 
PPTX
Pertemuan 1 Pemrograman Dasar
Disma Ariyanti W
 
PDF
C++ chapter 1
jasvinder162
 
PDF
[PBO] Pertemuan 5 - Polymorphism
rizki adam kurniawan
 
DOCX
Teknik pencarian heuristik
PutraMudaSihombing
 
DOCX
Makalah teori graf revisi2
Ratnasari Dwi A
 
PDF
dot net unit-1.pdf
Prof. Dr. K. Adisesha
 
PPTX
Basis Data - Pengenalan DML dan DDL
Walid Umar
 
PDF
Python - object oriented
Learnbay Datascience
 
Java: Inheritance
Tareq Hasan
 
[PBO] Pertemuan 6 - Abstrak
rizki adam kurniawan
 
MAC Address Table Management menggunakan Cisco Packet Tracer
Ryandika Alfarishi
 
Materi Augmented Reality
Fajar Baskoro
 
Queue
Sherly Uda
 
Pemrograman Mobile Unit 2 : Dasar-dasar Flutter
Akhmad Khanif Zyen
 
WHAT IS ABSTRACTION IN JAVA
sivasundari6
 
Modul Praktikum Sistem Basis Data
Wahyu Widodo
 
Methods in C#
Prasanna Kumar SM
 
Best practices in Java
Mudit Gupta
 
7. Queue (Struktur Data)
Kelinci Coklat
 
Pengantar robotika
Abdul Fauzan
 
Pertemuan 1 Pemrograman Dasar
Disma Ariyanti W
 
C++ chapter 1
jasvinder162
 
[PBO] Pertemuan 5 - Polymorphism
rizki adam kurniawan
 
Teknik pencarian heuristik
PutraMudaSihombing
 
Makalah teori graf revisi2
Ratnasari Dwi A
 
dot net unit-1.pdf
Prof. Dr. K. Adisesha
 
Basis Data - Pengenalan DML dan DDL
Walid Umar
 
Python - object oriented
Learnbay Datascience
 
Ad

Similar to Advanced Python, Part 1 (20)

PPTX
Object Oriented Programming.pptx
SAICHARANREDDYN
 
PDF
Unit 3-Classes ,Objects and Inheritance.pdf
Harsha Patil
 
PDF
Dive into Python Class
Jim Yeh
 
PPTX
Python OOPs
Binay Kumar Ray
 
PPTX
About Python
Shao-Chuan Wang
 
PPTX
Python advance
Mukul Kirti Verma
 
PDF
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
Mohammad Reza Kamalifard
 
PDF
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
Mohammad Reza Kamalifard
 
PDF
Object.__class__.__dict__ - python object model and friends - with examples
Robert Lujo
 
PPTX
OOP concepts -in-Python programming language
SmritiSharma901052
 
PPTX
Python lec4
Swarup Ghosh
 
PPTX
Advance python
pulkit agrawal
 
PPTX
Presentation_4516_Content_Document_20250204010703PM.pptx
MuhammadChala
 
PPTX
Unit – V Object Oriented Programming in Python.pptx
YugandharaNalavade
 
PPTX
OOP Concepts Python with code refrences.pptx
SofiMusic
 
DOCX
Python Metaclasses
Nikunj Parekh
 
PDF
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Maulik Borsaniya
 
PPTX
Object Oriented Programming in Python.pptx
grpvasundhara1993
 
PPTX
Class and Objects in python programming.pptx
Rajtherock
 
Object Oriented Programming.pptx
SAICHARANREDDYN
 
Unit 3-Classes ,Objects and Inheritance.pdf
Harsha Patil
 
Dive into Python Class
Jim Yeh
 
Python OOPs
Binay Kumar Ray
 
About Python
Shao-Chuan Wang
 
Python advance
Mukul Kirti Verma
 
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
Mohammad Reza Kamalifard
 
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
Mohammad Reza Kamalifard
 
Object.__class__.__dict__ - python object model and friends - with examples
Robert Lujo
 
OOP concepts -in-Python programming language
SmritiSharma901052
 
Python lec4
Swarup Ghosh
 
Advance python
pulkit agrawal
 
Presentation_4516_Content_Document_20250204010703PM.pptx
MuhammadChala
 
Unit – V Object Oriented Programming in Python.pptx
YugandharaNalavade
 
OOP Concepts Python with code refrences.pptx
SofiMusic
 
Python Metaclasses
Nikunj Parekh
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Maulik Borsaniya
 
Object Oriented Programming in Python.pptx
grpvasundhara1993
 
Class and Objects in python programming.pptx
Rajtherock
 
Ad

More from Zaar Hai (7)

PDF
When Less is More - Save Brain Cycles with GKE Autopilot and Cloud Run
Zaar Hai
 
PDF
Google auth dispelling the magic
Zaar Hai
 
PDF
Google auth - dispelling the magic
Zaar Hai
 
PDF
Deep into Prometheus
Zaar Hai
 
PDF
Dip into prometheus
Zaar Hai
 
PDF
Apache ignite - a do-it-all key-value db?
Zaar Hai
 
PDF
Advanced Python, Part 2
Zaar Hai
 
When Less is More - Save Brain Cycles with GKE Autopilot and Cloud Run
Zaar Hai
 
Google auth dispelling the magic
Zaar Hai
 
Google auth - dispelling the magic
Zaar Hai
 
Deep into Prometheus
Zaar Hai
 
Dip into prometheus
Zaar Hai
 
Apache ignite - a do-it-all key-value db?
Zaar Hai
 
Advanced Python, Part 2
Zaar Hai
 

Recently uploaded (20)

PDF
Test Bank, Solutions for Java How to Program, An Objects-Natural Approach, 12...
famaw19526
 
PDF
madgavkar20181017ppt McKinsey Presentation.pdf
georgschmitzdoerner
 
PDF
NewMind AI Monthly Chronicles - July 2025
NewMind AI
 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
PDF
Google’s NotebookLM Unveils Video Overviews
SOFTTECHHUB
 
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
PPTX
C Programming Basics concept krnppt.pptx
Karan Prajapat
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PDF
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
AbdullahSani29
 
PDF
Software Development Methodologies in 2025
KodekX
 
PDF
This slide provides an overview Technology
mineshkharadi333
 
PDF
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PPTX
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
PPTX
The Power of IoT Sensor Integration in Smart Infrastructure and Automation.pptx
Rejig Digital
 
PPTX
Smart Infrastructure and Automation through IoT Sensors
Rejig Digital
 
PDF
Doc9.....................................
SofiaCollazos
 
PDF
Enable Enterprise-Ready Security on IBM i Systems.pdf
Precisely
 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
Test Bank, Solutions for Java How to Program, An Objects-Natural Approach, 12...
famaw19526
 
madgavkar20181017ppt McKinsey Presentation.pdf
georgschmitzdoerner
 
NewMind AI Monthly Chronicles - July 2025
NewMind AI
 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
Google’s NotebookLM Unveils Video Overviews
SOFTTECHHUB
 
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
C Programming Basics concept krnppt.pptx
Karan Prajapat
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
AbdullahSani29
 
Software Development Methodologies in 2025
KodekX
 
This slide provides an overview Technology
mineshkharadi333
 
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
The Power of IoT Sensor Integration in Smart Infrastructure and Automation.pptx
Rejig Digital
 
Smart Infrastructure and Automation through IoT Sensors
Rejig Digital
 
Doc9.....................................
SofiaCollazos
 
Enable Enterprise-Ready Security on IBM i Systems.pdf
Precisely
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 

Advanced Python, Part 1

  • 1. Topics in Advanced Python No agenda – jumping in... © 2014 Zaar Hai tech.zarmory.com
  • 2. Decorators Decorator is a function that accepts a function and returns another function from functools import wraps def deco(f): @wraps(f) def wrapper(*args, **kwargs): print "started at %s" % time.time() rv = f(*args, **kwargs) print "finished at %s" % time.time() return wrapper @deco def sleeper(): "Sleeper function" time.sleep(2) >>> sleeper() started at 1384245972.01 finished at 1384245974.01 >>> print sleeper.__name__ sleeper wraps takes care about wrapped aux data. Without it: >>> print sleeper.__name__ wrapper Important when reading online help of someone else's code 2 © 2014 Zaar Hai tech.zarmory.com
  • 3. Decorator usage examples To return cached values To implement retries To guard methods/functions with a lock To validate input/output of the function To limit function execution by a certain timeout Decorators greatly help with code reuse and Make code explicitly readable 3 © 2014 Zaar Hai tech.zarmory.com
  • 4. Decorator is just a function You can call decorators “inline” in your code @deco def sleeper(): pass sleeper() deco(sleeper)() @deco1 @deco2 def sleeper(): pass sleeper() deco1(deco2((sleeper))() Similarly, decorators themselves can accept parameters @deco(5) def sleeper(): pass sleeper() deco(5)(sleeper)() Note: The invocation order is a bit different Note:@deco(5) is executed when the code is imported 4 © 2014 Zaar Hai tech.zarmory.com
  • 5. Decorator with parameter - example $ cat mydeco.py def deco(p): print "got %s" % p def real_deco(f): @wraps(f) def wrapper(*args, **kwargs): print "decorating" return f(*args, **kwargs) return wrapper return real_deco @deco(5) def hello(): pass >>> import mydeco # outer function runs during import got 5 >>> mydeco.hello() # decorator runs when function executed decorating >>> 5 © 2014 Zaar Hai tech.zarmory.com
  • 6. Decorator can be a class Some times its useful to implement decorators as a class class deco(object): def __init__(self, p): self.p = p print "got %s" % p def __call__(self, f): @wraps(f) def wrapper(*args, **kwargs): print "decorating" return f(*args, **kwargs) return wrapper __call__ is a special method that is invoked when you try calling an object as if it was a function 6 © 2014 Zaar Hai tech.zarmory.com
  • 7. How does @property decorator work? @property – one of the most common decorators in Python class A(object): @property def a(self): return "a" >>> A().a 'a' But how does it work? 7 © 2014 Zaar Hai tech.zarmory.com
  • 8. Meet descriptors Descriptor is a protocol for accessing object attributes class A(object): def __init__(self): self.a = 1 >>> f = A(); f.a When you access a, what actually happens is v = self.__dict__["a"] if hasattr(v, '__get__'): return v.__get__(self) else: return v I.e. when attribute defines __get__ (or __set__) methods, they are called to produce (or set) actual attribute value 8 © 2014 Zaar Hai tech.zarmory.com
  • 9. Back to the @property @property implements both decorator and descriptor semantics like this: class Property(object): def __init__(self, getter): self.getter = getter def __get__(self, obj, csl): return self.getter(obj) class A(object): @Property def a(self): return "a" >>> o = A(); o.a 'a' >>> type(o.a) <type 'str'> 9 © 2014 Zaar Hai tech.zarmory.com
  • 10. Descriptors in action One-time caching of method's return values class OneTime(object): def __init__(self, func): self.func = func def __get__(self, obj, cls): to_augment = obj or cls rv = self.func(to_augment) pname = self.func.__name__ setattr(to_augment, pname, rv) return rv class BigMath(object): @OneTime def big_data(self): print "working hard...." return 42 Reusable – follows DRY principle More on this here and here class BigMath(object): def get_big_data(self): if hasattr(self, "_rv"): return self._rv self._rv = self._get_data() return self._rv def _get_data(self): print "working hard...." return 42 Nice, but leads to a lot of copy/paste code 10 © 2014 Zaar Hai tech.zarmory.com
  • 11. © 2014 Zaar Hai tech.zarmory.com Multiple inheritance “LEGO” goes on
  • 12. M-I in action - MixIns “MixIn” is a programming concept about creating aux class that enriches functionality of the main class class SteeringWheel(object): ... class HornMixIn(object): """Mix-in class to enable horn functionality""" def horn(self, *args, **kwargs): print "move over!" class CruiseControlMixIn(object): def cc_set(self): … def cc_cancel(self): ... def cc_restore(self):... class Mazda2SteeringWheel(CruiseControlMixIn, HornMixIn, SteeringWheel): """Sometimes there is nothing to configure here at all""" 12 © 2014 Zaar Hai tech.zarmory.com
  • 13. M-I in action – MixIns (continued) Here is another example class Synchronized(object): def __init__(self, *args, **kwargs): self._sync_lock = threading.Lock() super(Synchronized, self).__init__(*args, **kwargs) @staticmethod def synchronized(func): @wraps(func) def wrapper(self, *args, **kwargs): with self._sync_lock: return func(self, *args, **kwargs) return wrapper class Writer(Syncrhonized, Db): @Synchronized.synchronized def write(self, o): self.db.write(o) As we see, for a lot of real-live examples M-I can be used straight-forward and its behavior in Python “makes sense” 13 © 2014 Zaar Hai tech.zarmory.com
  • 14. “New style” classes Not exactly “new” - since Python 2.2 Always inherit from object Really, Always inherit from object Use super to call ancestor methods class Foo(object): def bar(self): pass class Bar(Foo): def bar(self): return super(Bar, self).bar() class Foo: def bar(self): pass class Bar(Foo): def bar(self): return Foo.bar(self) Following the above technique will make your and others' life much easier 14 © 2014 Zaar Hai tech.zarmory.com
  • 15. Multiple inheritance and MRO class A(object): def __init__(self): super(A, self).__init__() print "A" class B(object): def __init__(self): super(B, self).__init__() print "B" class C(A,B): def __init__(self): super(C, self).__init__() print "C" What will be output of running C()? “A B C”? “B A C”? How do we arrive from super(A..) to the method of B? 15 © 2014 Zaar Hai tech.zarmory.com
  • 16. Multiple inheritance and MRO MRO – method resolution order Python utilizes C3 algorithm >>> C.__mro__ (<class 'my2.C'>, <class 'my2.A'>, <class 'my2.B'>, <type 'object'>) And the answer to the previous question is “B A C” For most real-life example I've seen, C3 logic “makes sense” Without inheriting from object and using super, one had to do MRO by himself in the code. Bottom line – super() does not return ancestor, but the next member of MRO chain 16 © 2014 Zaar Hai tech.zarmory.com
  • 17. MRO pitfalls class A(object): pass class B(object): pass class C(A,B): pass class D(B,A): pass class E(C,D): pass Where super(E, self).__init__() will end up? 17 © 2014 Zaar Hai tech.zarmory.com
  • 18. MRO pitfalls class A(object): pass class B(object): pass class C(A,B): pass class D(B,A): pass class E(C,D): pass Where super(E, self).__init__() will end up? >>> class E(C,D): pass ... Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Error when calling the metaclass bases Cannot create a consistent method resolution order (MRO) for bases B, A There are cases when C3 would (and should) fail to prevent a naive programmer from creating a mess 18 © 2014 Zaar Hai tech.zarmory.com
  • 19. type function revised All of you are familiar with type: >>> class A(object): pass >>> a = A() >>> type(a) <class '__main__.A'> BTW, don't use type(a) == A, but isinstance(a, A) What type(A) will print? 19 © 2014 Zaar Hai tech.zarmory.com
  • 20. type function revised >>> type(A) <type 'type'> In Python, object model hierarchy has two levels: Objects are instances of their Class Classes are instances of their Type – AKA metaclass All classes by default are instances of type metaclass, but we can define our own metaclasses of course: class MetaA(type): pass class A(object): __metaclass__ = MetaA >>> type(A) <class '__main__.MetaA'> Metaclass can augment class creation. More on this later 20 © 2014 Zaar Hai tech.zarmory.com
  • 21. Yet another face of type function type can be used to create new classes on the fly The syntax: type(name, bases, dict) class Actor(object): def get(self, req): return self.val for c in [Volumes, Hosts]: class Conf(object): pass class Volumes(Conf): url = '/volumes' val = 5 class Hosts(Conf): url = '/hosts' val = 4 HandlerClass = type('Handler', (Actor, c), {}) HttpServer.addUrl(c.url, HandlerClass) HttpServer.start() Allows really decoupled design. Yet flexible and efficient. 21 © 2014 Zaar Hai tech.zarmory.com
  • 22. Metaclass example – proper Enum class UserRoles(Enum): root = 10 user = 20 user__desc = "Regular users" Nobody = 30 >>> UserRoles.root 10 >>> UserRoles.root.name 'root' # Wow, I have a name! >>> UserRoles.user.desc 'Regular users' # And even description >>> UserRoles.root == 10 True # I look and quack just like the native type I was assigned to >>> role = UserRoles(10) # Cast me! (with the DB value for example) >>> role; role.name; role == 10 10 'root' True >>> role == UserRoles.root True Magic? May be; but a simple one 22 © 2014 Zaar Hai tech.zarmory.com
  • 23. Magic revealed class EnumMeta(type): def __new__(mcs, name, base, d): cls = super(EnumMeta, mcs).__new__(mcs, name, base, d) for k, v in cls.__dict__.items(): pname = getattr(cls, k+"__name", k) pdesc = getattr(cls, k+"__desc", "") n = type(v).__name__ prop = type(n, (type(v),), {"name" : pname, "desc" : pdesc}) p = prop(v) setattr(cls, k, p) return cls class Enum(object): __metaclass__ = EnumMeta Full story here 23 © 2014 Zaar Hai tech.zarmory.com
  • 24. © 2014 Zaar Hai tech.zarmory.com Thank you …