An Introduction to the Zen of Python

Doug Hellmann February, 2011
Friday, February 18, 2011

The Zen of Python
by Tim Peters

• Beautiful is better than ugly. • Explicit is better than implicit. • Simple is better than complex. • Complex is better than

• There should be one – and

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.

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!

Friday, February 18, 2011

Beautiful is better than ugly.
• Write programs for human readers • Simple expression syntax • Consistent syntax and behavior

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Simple Expressions
1 2 3 4 5 6 7 8 9 10 11 12 i = 5 + 5 s = 'literal string' m = """multi-line string """ us = u'üñîçø∂é string' vals = [ 1, 3, 5, 7, ] vals[0] 13 14 15 16 17 18 19 20 21 22 23 24

t = ('a', 1, vals, None) t[1] d = { 'a':'a value', 'b':'b value', } d['a'] if a or b: do_something()

Friday, February 18, 2011

Explicit is better than implicit.
• Boolean type • No “hidden” loop variables • Use “self” to refer to object inside a method

Friday, February 18, 2011

Boolean Values

1 2 3 4 5 6 7 8 9 10 11 12 13 14

t = True f = False if t: print 't is true' if not f: print 'f is false' a = t or f b = t and f print a print b

$ python booleans.py t is true f is false True False

Friday, February 18, 2011

for loops

$ python for_loop.py 1 2 3 4 5 6 7 8 9 10 print 'Numbers:' for i in range(5): print i print print 'Letters:' for c in [ 'a', 'b', 'c' ]: print c Numbers: 0 1 2 3 4 Letters: a b c

Friday, February 18, 2011

Defining a Class
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Defining a Class
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Defining a Class
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Defining a Class
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Defining a Class
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Simple is better than complex.
• Garbage collection • print statement • Interactive interpreter for experimentation

Friday, February 18, 2011

Printing
1 2 3 4 5 6 7 8 9 10 11 12 13 # -*- encoding: utf-8 -*print 'string:', 'string' print 'unicode:', u'üñîçø∂é string' print 'number:', 5 * 5 my_list = [ 1, 'a', None ] print 'list:', my_list my_dict = { 'a':'a value', 'b':'b value' } print 'dict:', my_dict

$ python printing.py string: string unicode: üñîçø∂é string number: 25 list: [1, 'a', None] dict: {'a': 'a value', 'b': 'b value'}
Friday, February 18, 2011

Printing, with printf-style Formatting
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # -*- encoding: utf-8 -*my_list = [ 1, 'a', None ] my_dict = { 'a':'a value', 'b':'b value' } args = ('string', u'üñîçø∂é string', 5 * 5, my_list, my_dict) print ''' string : %s unicode: %s number : %d list : %s dict : %s ''' % args

$ python printing_with_format.py string : unicode: number : list : dict : string üñîçø∂é string 25 [1, 'a', None] {'a': 'a value', 'b': 'b value'}

Friday, February 18, 2011

Interactive Interpreter

Friday, February 18, 2011

Complex is better than complicated.
• Do complex things in a “Pythonic” way • SciPy and NumPy for advanced science and math

Friday, February 18, 2011

Interactive Graphic Environment
Friday, February 18, 2011

SciPy, NumPy, matplotlib

NumPy Performance

Standard Python
1 2 3 4 5 a = range(10000000) b = range(10000000) c = [] for i in range(len(a)): c.append(a[i] + b[i]) 1 2 3 4

NumPy
import numpy as np a = np.arange(10000000) b = np.arange(10000000) c = a + b

5-10 seconds

“nearly instantaneous”

Friday, February 18, 2011

Flat is better than nested.
• Wide variety of modules in standard library • Namespace is flat • No need to use long names: com.company.java.blah.blah

Friday, February 18, 2011

Standard Library Modules: Networking
• socket • select • SocketServer • BaseHTTPServer • asyncore • asynchat • xmlrpclib • SimpleXMLRPCServer

Friday, February 18, 2011

Standard Library Modules: Internet Protocols

• urllib • httplib • ftplib • smtpd

• smtplib • poplib • imaplib • json

Friday, February 18, 2011

Standard Library Modules: Command Line

• getopt • optparse • argparse

• fileinput • cmd • readline

Friday, February 18, 2011

Standard Library Modules: Parallel Processing

• subprocess • threading

• multiprocessing • Queue

Friday, February 18, 2011

Standard Library Modules: Databases

• anydbm • pickle

• shelve • sqlite3

Friday, February 18, 2011

Standard Library Modules: Miscellaneous
• datetime • grp • pwd • profile • timeit • struct • ctypes • xml • tarfile • csv

Friday, February 18, 2011

Sparse is better than dense.
• Standard library stays “shallow” • http://pypi.python.org/ • Allows separate release schedules • pip (“pip installs Python packages”)

Friday, February 18, 2011

Readability counts.
• Whitespace for block structures • Minimal punctuation • Built-in documentation • Extensive online documentation at http://docs.python.org/

Friday, February 18, 2011

Code Blocks
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Code Blocks
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Minimal Punctuation
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Minimal Punctuation
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Inline Documentation
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Inline Documentation
1 class MyClass(object): 2 """Class documentation. 3 """ 4 5 def __init__(self, arg1, arg2): 6 self.attr1 = arg1 7 self.attr2 = arg2 8 9 def do_something(self): 10 """Does some work and returns a value. 11 """ 12 return self.attr1 * self.attr2 13 14 obj = MyClass(1, 2) 15 print obj.do_something()

Friday, February 18, 2011

Special cases aren’t special enough to break the rules.
• Everything is an object • Methods and functions differ by scope • Dynamic typing and runtime attribute lookup • Most “features” in external modules

Friday, February 18, 2011

String Methods

1 2 3 4 5 6

print print print print print print

' string value '.split() ' string value '.strip() 'str' in ' string value ' 'CHUGALUG'.startswith('C') 'CHUGALUG'.endswith('end') ':'.join(['a', 'b', 'c'])

$ python string_methods.py ['string', 'value'] string value True True False a:b:c

Friday, February 18, 2011

String Methods

1 2 3 4 5 6

print print print print print print

' string value '.split() ' string value '.strip() 'str' in ' string value ' 'CHUGALUG'.startswith('C') 'CHUGALUG'.endswith('end') ':'.join(['a', 'b', 'c'])

$ python string_methods.py ['string', 'value'] string value True True False a:b:c

Friday, February 18, 2011

String Methods

1 2 3 4 5 6

print print print print print print

' string value '.split() ' string value '.strip() 'str' in ' string value ' 'CHUGALUG'.startswith('C') 'CHUGALUG'.endswith('end') ':'.join(['a', 'b', 'c'])

$ python string_methods.py ['string', 'value'] string value True True False a:b:c

Friday, February 18, 2011

String Methods

1 2 3 4 5 6

print print print print print print

' string value '.split() ' string value '.strip() 'str' in ' string value ' 'CHUGALUG'.startswith('C') 'CHUGALUG'.endswith('end') ':'.join(['a', 'b', 'c'])

$ python string_methods.py ['string', 'value'] string value True True False a:b:c

Friday, February 18, 2011

String Methods

1 2 3 4 5 6

print print print print print print

' string value '.split() ' string value '.strip() 'str' in ' string value ' 'CHUGALUG'.startswith('C') 'CHUGALUG'.endswith('end') ':'.join(['a', 'b', 'c'])

$ python string_methods.py ['string', 'value'] string value True True False a:b:c

Friday, February 18, 2011

String Methods

1 2 3 4 5 6

print print print print print print

' string value '.split() ' string value '.strip() 'str' in ' string value ' 'CHUGALUG'.startswith('C') 'CHUGALUG'.endswith('end') ':'.join(['a', 'b', 'c'])

$ python string_methods.py ['string', 'value'] string value True True False a:b:c

Friday, February 18, 2011

String Methods

1 2 3 4 5 6

print print print print print print

' string value '.split() ' string value '.strip() 'str' in ' string value ' 'CHUGALUG'.startswith('C') 'CHUGALUG'.endswith('end') ':'.join(['a', 'b', 'c'])

$ python string_methods.py ['string', 'value'] string value True True False a:b:c

Friday, February 18, 2011

Function and Method Scope

1 class MyClass(object): 2 3 def do_something(self, arg1, arg2): 4 return arg1 * arg2 5 6 def my_function(arg1, arg2): 7 return arg1 * arg2

Friday, February 18, 2011

Dynamic Attribute Lookup
1 2 3 4 5 6 7 8 9 10 class MyClass(object): CLASS_ATTR = 'class value' def __init__(self, arg): self.attr = arg o = MyClass('instance value') print o.attr print o.CLASS_ATTR

$ python dynamic_attribute_lookup.py instance value class value

Friday, February 18, 2011

Dynamic Typing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class A(object): def do_something(self): print 'in A' class B(object): def do_something(self): print 'in B' def work_on_obj(c): c.do_something() a = A() b = B() work_on_obj(a) work_on_obj(b) $ python dynamic_typing.py in A in B

Friday, February 18, 2011

Regular Expressions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import re pattern = 'this' text = 'Does this text match the pattern?' match = re.search(pattern, text) s = match.start() e = match.end() print print print print 'Found :', 'In :', 'Range :', 'Substring:', match.re.pattern match.string s, '-', e text[s:e]

$ python using_regex.py Found : this In : Does this text match the pattern? Range : 5 - 9 Substring: this
Friday, February 18, 2011

Although practicality beats purity.
• Multiple Programming Models • OOP • Procedural • Functional

Friday, February 18, 2011

Procedural
1 2 3 4 5 6 7 8 9 10 def my_function(arg1, arg2): """This function multiplies arg1 by arg2. """ return arg1 * arg2 results = [] for i in range(5): results.append(my_function(i, i)) print results $ python procedural.py [0, 1, 4, 9, 16]

Friday, February 18, 2011

Functional: List Comprehension
1 results = [ i*i for i in range(5) ] 2 3 print results

$ python functional.py [0, 1, 4, 9, 16]

Friday, February 18, 2011

Functional: List Comprehension
1 results = [ i*i for i in range(5) ] 2 3 print results

$ python functional.py [0, 1, 4, 9, 16]

Friday, February 18, 2011

Functional: List Comprehension
1 results = [ i*i for i in range(5) ] 2 3 print results

$ python functional.py [0, 1, 4, 9, 16]

Friday, February 18, 2011

Functional: List Comprehension
1 results = [ i*i for i in range(5) ] 2 3 print results

$ python functional.py [0, 1, 4, 9, 16]

Friday, February 18, 2011

Functional: Generator Expression
1 results = ( i*i for i in range(5) ) 2 3 print results 4 5 for i in results: 6 print i

1 2 3 4 5 6 7

$ python generator_expr.py <generator object <genexpr> at 0x1004d20a0> 0 1 4 9 16

Friday, February 18, 2011

Functional: Generators
1 def gen_values(n): 2 for i in range(n): 3 yield i*i 4 5 print gen_values(5) 6 7 for i in gen_values(5): 8 print i

1 2 3 4 5 6 7

$ python generator.py <generator object gen_values at 0x1004d2050> 0 1 4 9 16

Friday, February 18, 2011

Errors should never pass silently.
• Exception-based error handling • Tracebacks aid debugging

Friday, February 18, 2011

Exceptions and Tracebacks
1 def f(n): 2 if n > 0: 3 return n * f(n-1) 4 return 1 5 6 print f('5')

$ python traceback.py Traceback (most recent call last): File ".../traceback.py", line 6, in <module> print f('5') File ".../traceback.py", line 3, in f return n * f(n-1) TypeError: unsupported operand type(s) for -: 'str' and 'int'

Friday, February 18, 2011

Raising Exceptions
1 def f(n): 2 if not isinstance(n, int): 3 raise TypeError('n should be an int') 4 if n > 0: 5 return n * f(n-1) 6 return 1 7 8 print f('5')

$ python raising.py Traceback (most recent call last): File ".../raising.py", line 8, in <module> print f('5') File ".../raising.py", line 3, in f raise TypeError('n should be an int') TypeError: n should be an int

Friday, February 18, 2011

Raising Exceptions
1 def f(n): 2 if not isinstance(n, int): 3 raise TypeError('n should be an int') 4 if n > 0: 5 return n * f(n-1) 6 return 1 7 8 print f('5')

$ python raising.py Traceback (most recent call last): File ".../raising.py", line 8, in <module> print f('5') File ".../raising.py", line 3, in f raise TypeError('n should be an int') TypeError: n should be an int

Friday, February 18, 2011

Unless explicitly silenced.
• Catch exceptions with try:except • Process • Convert • Ignore

Friday, February 18, 2011

Catching Exceptions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def f(n): if not isinstance(n, int): raise TypeError('n should be an int') if n > 0: return n * f(n-1) return 1 try: print f('5') except TypeError, err: print 'Had an error:', err else: print 'No error' finally: print 'Always run' $ python catching.py Had an error: n should be an int Always run
Friday, February 18, 2011

In the face of ambiguity, refuse the temptation to guess.
• Coerce types only when not surprising • Cannot add strings and numbers • Can multiply them!

Friday, February 18, 2011

Type Coercion
1 2 3 4 print print print print 5 2 2 2 * 1.0 ** 100 * 'abc' + 'abc'

1 2 3 4 5 6 7 8

$ python type_coercion.py 5.0 1267650600228229401496703205376 abcabc Traceback (most recent call last): File ".../type_coercion.py", line 4, in <module> print 2 + 'abc' TypeError: unsupported operand type(s) for +: 'int' and 'str'

Friday, February 18, 2011

Type Coercion
1 2 3 4 print print print print 5 2 2 2 * 1.0 ** 100 * 'abc' + 'abc'

1 2 3 4 5 6 7 8

$ python type_coercion.py 5.0 1267650600228229401496703205376 abcabc Traceback (most recent call last): File ".../type_coercion.py", line 4, in <module> print 2 + 'abc' TypeError: unsupported operand type(s) for +: 'int' and 'str'

Friday, February 18, 2011

Type Coercion
1 2 3 4 print print print print 5 2 2 2 * 1.0 ** 100 * 'abc' + 'abc'

1 2 3 4 5 6 7 8

$ python type_coercion.py 5.0 1267650600228229401496703205376 abcabc Traceback (most recent call last): File ".../type_coercion.py", line 4, in <module> print 2 + 'abc' TypeError: unsupported operand type(s) for +: 'int' and 'str'

Friday, February 18, 2011

Type Coercion
1 2 3 4 print print print print 5 2 2 2 * 1.0 ** 100 * 'abc' + 'abc'

1 2 3 4 5 6 7 8

$ python type_coercion.py 5.0 1267650600228229401496703205376 abcabc Traceback (most recent call last): File ".../type_coercion.py", line 4, in <module> print 2 + 'abc' TypeError: unsupported operand type(s) for +: 'int' and 'str'

Friday, February 18, 2011

Type Coercion
1 2 3 4 print print print print 5 2 2 2 * 1.0 ** 100 * 'abc' + 'abc'

1 2 3 4 5 6 7 8

$ python type_coercion.py 5.0 1267650600228229401496703205376 abcabc Traceback (most recent call last): File ".../type_coercion.py", line 4, in <module> print 2 + 'abc' TypeError: unsupported operand type(s) for +: 'int' and 'str'

Friday, February 18, 2011

There should be one – and preferably only one – way to do it.
• Eliminate redundancy • Easier to learn • Easier to remember

Friday, February 18, 2011

Index API
1 2 3 4 5 6 7 8 9 10 11 12 13 a = [ 1, 2, 3 ] print a[0] a = (1, 2, 3) print a[0] a = 'abc' print a[0] a = {0:'zero value', 1:'one value', } print a[0] $ python index_api.py 1 1 a zero value

Friday, February 18, 2011

Although that way may not be obvious at first unless you’re Dutch.
• GUI • GTK • KDE • Cocoa • MS Windows • Tk • wxPython • Web • Django • AppEngine • Pyramid • Flask • TurboGears • Pecan

Friday, February 18, 2011

Now is better than never.
• ctypes • Jython • IronPython • Python 2 vs. Python 3

Friday, February 18, 2011

Although never is often better than right now.
• Language moratorium • Not everything goes into stdlib any more

Friday, February 18, 2011

If the implementation is hard to explain, it’s a bad idea.
Friday, February 18, 2011

Python Enhancement Proposals

If the implementation is easy to explain, it may be a good idea.

Friday, February 18, 2011

Namespaces are one honking great idea – let’s do more of those!
Closures

Friday, February 18, 2011

Closures
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def outer(arg): print 'outer(%s)' % arg def inner(val): print 'inner(%s) (arg=%s)' % (val, arg) return val * arg return inner print 'Creating thrice:' thrice = outer(3) print '\nCalling thrice:' print thrice(3) print thrice('a')

Friday, February 18, 2011

Closures
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def outer(arg): print 'outer(%s)' % arg def inner(val): print 'inner(%s) (arg=%s)' % (val, arg) return val * arg return inner print 'Creating thrice:' thrice = outer(3) print '\nCalling thrice:' print thrice(3) print thrice('a') $ python closure.py Creating thrice: outer(3) Calling thrice: inner(3) (arg=3) 9 inner(a) (arg=3) aaa

Friday, February 18, 2011

References
• http://docs.python.org/ • http://www.doughellmann.com/ PyMOTW/ • Learning Python by Mark Lutz • Python Essential Reference by David Beazley • The Python Standard Library by Example by Doug Hellmann • http://us.pycon.org/

Friday, February 18, 2011

Questions?

Friday, February 18, 2011

Image Credits
1. http://www.gaialandscapedesignbackgrounds.net/landscape_design_architecture_background_Zen_Garden_chan3.htm 3. http://www.flickr.com/photos/grabadonut/539151245/sizes/l/in/photostream/ 13. http://www.flickr.com/photos/tobascodagama/3106398602/ 17. http://www.flickr.com/photos/benandliz/11065336/ 21 & 22. http://scipy.org 24. http://www.otherlandtoys.co.uk/russian-matryoshka-nesting-dolls-pieces-p-2126.html 32. http://www.dandelionsummers.com/html/building_block.html 36. http://www.flickr.com/photos/photoinference/2494576240/in/faves-40068198@N04/ 47. http://www.flickr.com/photos/smithsonian/3112472619/in/faves-40068198@N04/ 54. http://www.flickr.com/photos/mherring/3722272868/sizes/l/in/photostream/ 57. http://www.webstaurantstore.com/9-3-4-x-4-1-2-unbleached-natural-coffee-filter-12-cup-1000-cs/121CF12U.html 59. http://brainstorm-services.com/wcu-lit/ambiguity.html 66. http://commons.wikimedia.org/wiki/File:Dutch_windmill.jpg 67. http://www.epicpm.org/epic-blogging 68. http://www.skyscanner.net/news/articles/2009/09/002990-travel-tip-10-get-on-last-and-learn-the-art-of-patience.html 69. http://gizmodo.com/5015735/the-top-10-rube-goldberg-machines-featured-on-film 71. http://www.nutricaplabs.com/capsule-manufacturer.aspx 75. http://wmltech.wordpress.com/2006/12/09/got-questions/

Friday, February 18, 2011

Sign up to vote on this title
UsefulNot useful