Awesome
mkupidura@future-processing.com
@__fwkz__
What makes Python awesome?
Winning features
-
indentation,
-
iterator protocol,
-
list comps, set comps, dict comps and genexps
-
generators,
-
decorators,
-
context menagers,
-
metaclasses,
-
Abstract Base Classes
Indentation
- This is how we write our pseudo code
- Clean and intuitive
- Indentation never lies
Indentation
for (i=0; i<10; i++);
printf("Nalesnikiii?!");
for i in xrange(10):
print("Nalesnikiii?!")
Iterator protocol
EVERYWHERE
Iterables:
- strings,
- lists,
- sets,
- dicts,
- files,
- itertools,
- ...
Things that consume iterators:
- for-loops,
- min(),
- max(),
- sorted(),
- sum(),
- set(),
- list(),
- tuple(),
- dict(),
- itertools
- ...
Can be chained like UNIX pipes and filters
sorted(set('abracadabra'))
sorted(set(open('lista_wildsteina.txt')))
sum(shares*price for symbol, shares, price in port)
cat lista_widsteina.txt | sort | uniq
SELECT SUM(shares*price) from port;
list comprehensions
-
one of the most loved Python feature,
-
derived from mathematics notation,
-
clean and beautiful,
-
much flexible and expressive than map, filter, reduce...
#Sum of powers
new_list = []
for x in xrange(1000):
new_list.append(x**2)
sum_of_powers = sum(new_list)
# list comps!
sum_of_powers = sum([x**2 for x in xrange(1000)])
#Fresh fruits
fresh_fruits = []
for fruit in fruits:
if not fruit.rotten:
fresh_fruits.append(fruit)
# list comps!
fresh_fruits = [fruit for fruit in fruits if not fruit.rotten]
#Agent?
[line.upper() for line in open('lista_wildsteina.txt')
if 'Kupidura' in line]
Generators
-
Easiest way to write iterator
-
Simple syntax, only adds the YIELD keyword
-
Remember state beetween invocations
-
ACCEPT INPUT!
#Build and return a list
def firstn(n):
num, nums = 0, []
while num < n:
nums.append(num)
num += 1
return nums
sum_of_first_n = sum(firstn(1000000))
for x in firstn():
# complicated processing
#a generator that yields items instead of returning a list
def firstn(n):
num = 0
while num < n:
yield num
num += 1
sum_of_first_n = sum(firstn(1000000))
for x in firstn():
# complicated processing
Generators accept inputs!
class Malfunction(Exception):
pass
def my_generator():
print 'starting up'
val = yield 1
print 'got:', val
val = yield 2
print 'got:', val
try:
yield 3
except Malfunction:
print 'malfunction!'
yield 4
print 'done'
gen = my_generator()
print gen.next() # start the generator
print gen.send(10) # send the value 10
print gen.send(20) # send the value 20
print gen.throw(Malfunction()) # raise an exception inside the generator
try:
gen.next()
except StopIteration:
pass
Decorators
- expressive,
- easy on eyes,
- works for functions, methods, classes,
- extremly reusable
@dec2
@dec1
def func(arg1, arg2, ...):
pass
#This is equivalent to:
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
from bottle import get, post, request
@get('/login')
def login():
return '''
<form action="/login" method="post">
Username: <input name="username" type="text" />
Password: <input name="password" type="password" />
<input value="Login" type="submit" />
</form>
'''
@post('/login')
def do_login():
username = request.forms.get('username')
password = request.forms.get('password')
if check_login(username, password):
return "<p>Your login information was correct.</p>"
else:
return "<p>Login failed.</p>"
Context managers
-
elegant resource management,
-
powerful tool for refactoring code,
-
factors-out common setup and teardown code
with open("lista_wildsteina.txt") as f:
print f.read()
with locking:
access_resource()
with ignore(OSError):
os.remove(file)
formal way to define interfaces in Python, while staying true to the spirit of duck-typing
Abstract Base Classes
allows to customize the behaviour of isinstance() and issubclass()
class Container:
__metaclass__ = ABCMeta
@abstractmethod
def __contains__(self, x):
return False
@classmethod
def __subclasshook__(cls, C):
if cls is Container:
if _hasattr(C, "__contains__"):
return True
return NotImplemented
class ContainAllTheThings(object):
def __contains__(self, item):
return True
print(issubclass(ContainAllTheThings, collections.Container))
# prints True
print(isinstance(ContainAllTheThings(), collections.Container))
# prints True
If you implement the right interface, you're a subclass!
class PageHandler:
"""
Base class for page object handlers
"""
__metaclass__ = ABCMeta
def __init__(self, driver, scenario):
self.driver = driver
self.scenario = scenario
self.page_object = self.page_object(driver, scenario)
@abstractproperty
def page_object(self):
""" Binds PageHandler to certain Page Object Model """
@abstractmethod
def execute(self):
""" Execute Page Object handler. """
class LoginHandler(PageHandler):
def do_something(self):
pass
login = LoginHandler(driver, scenario)
"""
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class LoginHandler
with abstract methods execute, page_object
"""
Raymond Hettinger
@raymondh
"Please take this presentation and be me."
https://www.youtube.com/watch?v=NfngrdLv9ZQ
Awesome Python
By fwkz
Awesome Python
- 1,322