New stuff in Python 2.2




(page 1)


Easy stuff





> >> import sys
> >> sys.maxint
2147483647
> >> sys.maxint + 1
2147483648L
> >> # No overflow!


(page 2)


Iterators





for line in open('/etc/passwd'):
# do something with line


> >> iter(open('/etc/passwd'))


(page 3)


Using Iterators




> >> i = iter(range(3))
> >> i

> >> i.next()
0
> >> i.next()
1
> >> i.next()
2
> >> i.next()
Traceback (most recent call last):
File " ", line 1, in ?
StopIteration
> >>

(page 4)


Writing your own Iterator







(page 5)


Generators







from __future__ import generators
def fib():
a, b = 0, 1
while 1:
yield b
a, b = b, a+b

(page 6)


fib in action



> >> g = fib()
> >> g

> >> g.next()
1
> >> g.next()
1
> >> g.next()
2
> >> g.next()
3
> >> g.next()
5
> >> g.next()
8
> >> g.next()
13

(page 7)


fib in action again



> >> g = fib()
> >> for n, f in zip(range(10), g): print n, f
...
0 1
1 1
2 2
3 3
4 5
5 8
6 13
7 21
8 34
9 55

(page 8)


Generators explained







(page 9)


Generators continued






(page 10)


staticmethod




> >> class C:
... def foo(x, y): # No self!
... print 'static method foo:', x, y
... foo = staticmethod(foo)
...
> >> C.foo(1,2)
static method foo: 1 2
> >> c = C()
> >> c.foo(1,2)
static method foo: 1 2

(page 11)


classmethod




> >> class C:
... def foo(cls, x, y):
... print 'class method foo:', cls, x, y
... foo = classmethod(foo)
...
> >> C.foo(1,2)
class method foo: __main__.C 1 2
> >> c = C()
> >> c.foo(1,2)
class method foo: __main__.C 1 2
> >> class D(C): pass
...
> >> D.foo(1,2)
class method foo: __main__.D 1 2

(page 12)


How does staticmethod work?



> >> def smethod(x):
... class staticmethod(object):
... def __init__(self, x):
... self.x = x
... def __get__(self, obj, class_=None):
... # Always return an unmolested object
... return self.x
... return staticmethod(x)
...
> >> # Test it
> >> class C:
... def f(x,y): print 'f', x, y
... f = smethod(f)
...
> >> C.f(1,2)
f 1 2
> >> C().f(1,2)
f 1 2

(page 13)


So what the hell is __get__?!






(page 14)


Descriptors continued



instance.attribute

attribute.__get__(instance, instance.__class__)

MyClass.attribute

attribute.__get__(None, MyClass)


(page 15)


Properties




class C(object):
def __init__(self):
self.__x = 0

def getx(self):
return self.__x

def setx(self, x):
if x < 0: x = 0
self.__x = x

x = property(getx, setx)

(page 16)


Properties continued



> >> a = C()
> >> a.x = 10
> >> print a.x
10
> >> a.x = -10
> >> print a.x
0
> >> a.setx(12)
> >> print a.getx()
12
> >>



(page 17)


But hang on a second!






class Foo(object):
# What the hell is "object"?!



(page 18)


Type/Class unification






(page 19)


Subclassing builting types




class defaultdict(dict):
def __init__(self, default=None):
dict.__init__(self)
self.default = default

def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default

(page 20)


Builtin types are classes






> >> l = [1,2,3]
> >> if type(l) is list: print 'yep'
...
yep
> >> # No need to use types.ListType!

(page 21)


object and type




class C(object):
"""I am a new-style class,
because I inherit from object"""


> >> object, type, int
( , , )
> >> object.__bases__, type.__bases__, int.__bases__
((), ( ,), ( ,))
> >> type(object), type(type), type(int)
( , , )

(page 22)


Subclassing immutable types






> >> class SquaringTuple(tuple):
... def __init__(self, *args):
... tuple.__init__(self, [x**2 for x in args])
...
> >> t = SquaringTuple(1, 2, 3)
Traceback (most recent call last):
File " ", line 1, in ?
TypeError: tuple() takes at most 1 argument (3 given)

(page 23)


__new__




> >> class SquaringTuple(tuple):
... def __new__(cls, *args):
... return tuple.__new__(cls, [x**2 for x in args])
...
> >> t = SquaringTuple(1, 2, 3)
> >> t
(1, 4, 9)



(page 24)


__new__ continued






(page 25)


__slots__







(page 26)


__slots__ continued




> >> class C(object):
... __slots__ = ['x', 'y']
...
> >> c = C()
> >> c.x = 1
> >> c.x
1
> >> c.z = 2
Traceback (most recent call last):
File " ", line 1, in ?
AttributeError: 'C' object has no attribute 'z'

(page 27)


Metaclasses







(page 28)


Metaclasses in 1 easy slide



> >> class capitalise(type):
... def __init__(cls, name, bases, dict):
... type.__init__(cls, name, bases, dict)
... for name in dict:
... NAME = name.upper()
... if NAME not in dict:
... setattr(cls, NAME, dict[name])
...
> >> class C:
... __metaclass__ = capitalise
... def foo(self):
... print 'foo'
...
> >> c = C()
> >> c.foo()
foo
> >> c.FOO()
foo


(page 29)


Secret-Ultra-Mega Bonus: Python 2.3




> >> s = "Hello from Guido's time machine!'
> >> for index, word in enumerate(s.split()):
... print index, word
...
0 Hello
1 from
2 Guido's
3 time
4 machine!



(page 30)


Python 2.3 continued




> >> range(10)[::-2]
[9, 7, 5, 3, 1]





(page 31)


Links






(page 32)