Python 3 – Advanced Topics

General

List comprehensions

[(x,y) for x in [1,2,3] for y in [4,1,5] if x!=y]

v = [[1,2],[3,4]]
[n for e in v for n in e]

Static variables

class Foo:
    x = 1
    def inc(self):
        self.x += 1
    def class_inc(self):
        Foo.x += 2
    def class_inc2(self):
        self.__class__.x += 3
    @classmethod
    def class_inc3(cls):
        cls.x += 4
    def show(self):
        print("Foo.x="+str(Foo.x), "foo.x="+str(self.x))

foo = Foo()
foo.show()
Foo.x = 0
foo.show()
foo.inc()
foo.show()
foo.class_inc()
foo.show()
foo.class_inc2()
foo.show()
foo.class_inc3()
foo.show()
del foo.x
foo.show()

XML

import sys
import xml.etree.ElementTree

tree = xml.etree.ElementTree.parse("test.html")
root = tree.getroot()
notes = root.findall(".//p[@class='note']/a[@href]")
for note in notes:
    print(note.attrib['href'] + ": " + note.text)

Decorators

def decorate(fun):
    def tmp(*args, **kwargs):
        print("Calling "+fun.__name__)
        return fun(*args, **kwargs)
    return tmp

@decorate                             # foo = decorate(foo)
def foo(s):
    print("Hello",s)

foo("Wojtek")

Coroutine decorator:

def coroutine(func):
    def start(*args,**kwargs):
        c = func(*args,**kwargs)
        next(c)
        return c
    return start

Closures

def outer(x):
    def inner():
        print x
    return inner

print1 = outer(1)
print2 = outer(2)
print1()
1
print2()
2
print1.__closure__

Generators

import itertools
iterator.next()       # python 2
iterator.__next__()   # python 3
__iter__()            # returns an iterator

b = (2*x for x in a)  # b is a generator

g = gen()
next(g)               # equivalent to g.__next__()

Info:

Future statements

https://docs.python.org/2/reference/simple_stmts.html#future-statements

from __future__ import print_function