Cool Features of Python
Mafinar Khan, Product Manager
Panacea Systems Limited
http://www.bdpanacea.com
@mafinar
In this presentation...
- What makes Python pleasant
- What makes Python powerful
- What makes Python productive
- import this; the Philosophy within
- Way too many P's...
Pleasant Python
- Easy to get up and running
- Fully Object Oriented
- Dynamic & Strongly typed
- "Executable Pseudo-code"
- Conventions in the blood-stream
- Philosophy driven
- PEP8
Python Syntax Tidbits
- Python's white spaces are important
- Python compound statements end with ":" and start a scope with leading white-space
- Python has "if", "while", "for..in", "with..as"
- Python "else if" is written "elif"
- Python supports Multiple Inheritance
- Python has some magic functions that start and end with __
- Python can do operator overloading
- Python's List Comprehension is hell fun!
Operator Overloading
class Product(object):
def __init__(self, name, price):
self.name, self.price = name, price
def __add__(self, other):
return self.price + other.price
def __call__(self, *args, **kwargs):
return "PRODUCT: {} @ Tk {}".format(self.name, self.price)
a = Product("Apple", 160.00)
o = Product("Orange", 140.00)
assert a + o == 300
assert a() == "PRODUCT: Apple @ Tk 160.00"
List Comprehensions
# List
[i**2 for i in range(100)]
# A bit complex
[item for sublist in l for item in sublist]
# In two dimensions
[[c for c in line] for line in f]
# With guards
[i for i in range(100) if i%2]
# Works with set too
{i for i in [1,2,3,3,3,4,1,12,2,3,4]}
Powerful Python
- Fully Object Oriented
- Duck-typing
- Functional Programming
- Decorators and Generators
- Advanced Object Oriented Constructs
- Metaclasses
Functional Programming in Python
- Functions are first class citizens
- Single expression lambda's are available
- Higher order Functions (map, reduce, filter)
- Decorators
- List/Set/Dictionary Comprehensions
Examples...
# Mathematics: f(x) = 2*x + 1
f = lambda x: 2*x + 1
is_odd = lambda x: not x%2
to_the_two = lambda limit: map(lambda x: x**2, range(limit)) # MAP
filter(is_odd, range(100)) # FILTER
reduce(lambda x,y: x+y, range(10)) # REDUCE
# Combine them all
import operator
reduce(operator.__add__, filter(is_odd, to_the_two(100)))
Decorators
- Function wrapping other functions
- Function takes a functions in, spits a function out.
- Useful in hiding complex details from function implementors
- Example: staticmethod, classmethod, login_required, expose, render_to
- Mathematical analogy (somewhat): gof and fog.
Example (Decorator)
def bold_maker(f):
def _wrap(f, *args, **kwargs):
return "<b>{}</b>".format(f(*args, **kwargs))
return _wrap
@bold_maker
def greet(name):
return "Hello {}".format(name.capitalize())
# Alternatively
greet = bold_maker(lambda name: "Hello {}".format(name.capitalize())
Play around with itertools for more powerful Python Functional Programming constructs
Productive Python
- Pleasant + Powerful = Productive
- Fun with shell, dir, and help
- Readability begets maintainability
- Insanely big ecosystem
- Amazing tools and frameworks
- <3 Open Source
Multiple Inheritance
- Depth First Search from Left-to-Right
- (New Style) In case of duplicate parents, all but last get removed
- Use __mro__ to find out the method resolution order
- If A(object), B(A), C(A) and D(B, C) the resolution order would be [ D, B, C, A, object ] ([D, B, A, C, A] with all but last A gone)
- Don't you just love __magic_methods__ ???
Fun with Objects
# Making methods case insensitive
class Person(object):
def name(self):
return "<NAME>"
def age(self):
return "<AGE>"
def __getattr__(self, value):
for i in type(self).__dict__.keys():
if value.lower() == i.lower():
return getattr(self, i)
return "UNDEFINED"
p = Person()
"Name: {}; Age: {}".format(p.NaME(), p.AGE())
Fun Continues...
class Container(object):
def __init__(self, numbers):
self.numbers = numbers
def add(self, number):
self.numbers.append(number)
def __getattr__(self, attr):
if attr.startswith("get_"):
suffix = "_".join(attr.split("_")[1:])
if suffix == "odd_numbers":
return lambda: filter(lambda x: x%2 == 1, self.numbers)
if suffix == "less_than":
return lambda n: filter(lambda x: x < n, self.numbers)
c = Container(range(100))
c.get_odd_numbers(); c.get_less_than(50)
This is why Python has so many Beautiful Frameworks!
Python's Philosophy
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Also, PEP8...
My Favorite Python Tools/Frameworks
- Django
- Twisted
- BeautifulSoup
- Matplotlib
- NLTK
- Reportlab
- Numpy
- Pandas
- Jinja2
Thank You!!!
Cool Features of Python Programming Language
By Mafinar Khan
Cool Features of Python Programming Language
Presentation slides for my talk in Pycon Dhaka 2014. In here, I talk about some of my favorite features of Python's syntax, as well as an extremely short lived tour of the basic Python syntax, in the end, I close with mentioning the philosophy of Python and what is meant by being "Pythonic"
- 2,406