KEMBAR78
An Introduction to the Zen of Python | KEY
An Introduction to
the Zen of Python

     Doug Hellmann
     February, 2011
The Zen of Python
by Tim Peters


• Beautiful is better than ugly.         • There should be one – and
• Explicit is better than implicit.        preferably only one – obvious way
• Simple is better than complex.           to do it.
• Complex is better than                 • Although that way may not be
  complicated.                             obvious at first unless you're
• Flat is better than nested.              Dutch.
• Sparse is better than dense.           • Now is better than never.
• Readability counts.                    • Although never is often better than
• Special cases aren't special             *right* now.
  enough to break the rules.             • If the implementation is hard to
• Although practicality beats purity.      explain, it's a bad idea.
• Errors should never pass silently.     • If the implementation is easy to
• Unless explicitly silenced.              explain, it may be a good idea.
• In the face of ambiguity, refuse the   • Namespaces are one honking
  temptation to guess.                     great idea – let's do more of those!
Beautiful is better
than ugly.

• Write programs for human
  readers


• Simple expression syntax


• Consistent syntax and
  behavior
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Simple Expressions

 1   i = 5 + 5                13
 2                            14   t = ('a', 1, vals, None)
 3   s = 'literal string'     15   t[1]
 4                            16
 5   m = """multi-line        17   d = { 'a':'a value',
 6   string                   18          'b':'b value',
 7   """                      19         }
 8                            20   d['a']
 9   us = u'üñîçø∂é string'   21
10                            22   if a or b:
11   vals = [ 1, 3, 5, 7, ]   23       do_something()
12   vals[0]                  24
Explicit is better than
implicit.

• Boolean type


• No “hidden” loop variables


• Use “self” to refer to object
  inside a method
Boolean Values


     1   t = True
     2   f = False
     3
     4   if t:
     5       print 't is true'
                                  $ python booleans.py
     6
                                  t is true
     7   if not f:
                                  f is false
     8       print 'f is false'
                                  True
     9
                                  False
    10   a = t or f
    11   b = t and f
    12
    13   print a
    14   print b
for loops


                                      $ python for_loop.py

    1   print 'Numbers:'              Numbers:
    2                                 0
    3   for i in range(5):            1
    4       print i                   2
    5                                 3
    6   print                         4
    7   print 'Letters:'
    8                                 Letters:
    9   for c in [ 'a', 'b', 'c' ]:   a
   10       print c                   b
                                      c
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()
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()
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()
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()
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()
Simple is better than
complex.

• Garbage collection


• print statement


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

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

• Do complex things in a
  “Pythonic” way


• SciPy and NumPy for
  advanced science and math
Interactive Graphic
                      SciPy, NumPy, matplotlib
       Environment
NumPy Performance


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



          5-10 seconds                “nearly instantaneous”
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
Standard Library Modules: Networking


        • socket           • asyncore


        • select           • asynchat


        • SocketServer     • xmlrpclib


        • BaseHTTPServer   • SimpleXMLRPCServer
Standard Library Modules: Internet Protocols



               • urllib    • poplib


               • httplib   • imaplib


               • ftplib    • json


               • smtpd


               • smtplib
Standard Library Modules: Command Line


            • getopt     • fileinput


            • optparse   • cmd


            • argparse   • readline
Standard Library Modules: Parallel Processing



            • subprocess   • multiprocessing


            • threading    • Queue
Standard Library Modules: Databases




              • anydbm   • shelve


              • pickle   • sqlite3
Standard Library Modules: Miscellaneous

            • datetime   • struct


            • grp        • ctypes


            • pwd        • xml


            • profile    • tarfile


            • timeit     • csv
Sparse is better than
dense.

• Standard library stays
  “shallow”


• http://pypi.python.org/


• Allows separate release
  schedules


• pip (“pip installs Python
  packages”)
Readability counts.

• Whitespace for block
  structures


• Minimal punctuation


• Built-in documentation


• Extensive online
  documentation at http://
  docs.python.org/
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()
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()
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()
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()
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()
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()
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
String Methods



                                           $ python string_methods.py
  1   print   ' string value '.split()     ['string', 'value']
  2   print   ' string value '.strip()     string value
  3   print   'str' in ' string value '    True
  4   print   'CHUGALUG'.startswith('C')   True
  5   print   'CHUGALUG'.endswith('end')   False
  6   print   ':'.join(['a', 'b', 'c'])    a:b:c
String Methods



                                           $ python string_methods.py
  1   print   ' string value '.split()     ['string', 'value']
  2   print   ' string value '.strip()     string value
  3   print   'str' in ' string value '    True
  4   print   'CHUGALUG'.startswith('C')   True
  5   print   'CHUGALUG'.endswith('end')   False
  6   print   ':'.join(['a', 'b', 'c'])    a:b:c
String Methods



                                           $ python string_methods.py
  1   print   ' string value '.split()     ['string', 'value']
  2   print   ' string value '.strip()     string value
  3   print   'str' in ' string value '    True
  4   print   'CHUGALUG'.startswith('C')   True
  5   print   'CHUGALUG'.endswith('end')   False
  6   print   ':'.join(['a', 'b', 'c'])    a:b:c
String Methods



                                           $ python string_methods.py
  1   print   ' string value '.split()     ['string', 'value']
  2   print   ' string value '.strip()     string value
  3   print   'str' in ' string value '    True
  4   print   'CHUGALUG'.startswith('C')   True
  5   print   'CHUGALUG'.endswith('end')   False
  6   print   ':'.join(['a', 'b', 'c'])    a:b:c
String Methods



                                           $ python string_methods.py
  1   print   ' string value '.split()     ['string', 'value']
  2   print   ' string value '.strip()     string value
  3   print   'str' in ' string value '    True
  4   print   'CHUGALUG'.startswith('C')   True
  5   print   'CHUGALUG'.endswith('end')   False
  6   print   ':'.join(['a', 'b', 'c'])    a:b:c
String Methods



                                           $ python string_methods.py
  1   print   ' string value '.split()     ['string', 'value']
  2   print   ' string value '.strip()     string value
  3   print   'str' in ' string value '    True
  4   print   'CHUGALUG'.startswith('C')   True
  5   print   'CHUGALUG'.endswith('end')   False
  6   print   ':'.join(['a', 'b', 'c'])    a:b:c
String Methods



                                           $ python string_methods.py
  1   print   ' string value '.split()     ['string', 'value']
  2   print   ' string value '.strip()     string value
  3   print   'str' in ' string value '    True
  4   print   'CHUGALUG'.startswith('C')   True
  5   print   'CHUGALUG'.endswith('end')   False
  6   print   ':'.join(['a', 'b', 'c'])    a:b:c
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
Dynamic Attribute Lookup

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



          $ python dynamic_attribute_lookup.py
          instance value
          class value
Dynamic Typing

   1   class A(object):
   2       def do_something(self):
   3           print 'in A'
   4
   5   class B(object):              $ python dynamic_typing.py
   6       def do_something(self):   in A
   7           print 'in B'          in B
   8
   9   def work_on_obj(c):
  10       c.do_something()
  11
  12   a = A()
  13   b = B()
  14
  15   work_on_obj(a)
  16   work_on_obj(b)
Regular Expressions
         1   import re
         2
         3   pattern = 'this'
         4   text = 'Does this text match the pattern?'
         5
         6   match = re.search(pattern, text)
         7
         8   s = match.start()
         9   e = match.end()
        10
        11   print   'Found    :',   match.re.pattern
        12   print   'In       :',   match.string
        13   print   'Range    :',   s, '-', e
        14   print   'Substring:',   text[s:e]

       $ python using_regex.py
       Found    : this
       In       : Does this text match the pattern?
       Range    : 5 - 9
       Substring: this
Although practicality
beats purity.

• Multiple Programming Models


  • OOP


  • Procedural


  • Functional
Procedural

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


                    $ python procedural.py
                    [0, 1, 4, 9, 16]
Functional: List Comprehension

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




                $ python functional.py
                [0, 1, 4, 9, 16]
Functional: List Comprehension

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




                $ python functional.py
                [0, 1, 4, 9, 16]
Functional: List Comprehension

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




                $ python functional.py
                [0, 1, 4, 9, 16]
Functional: List Comprehension

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




                $ python functional.py
                [0, 1, 4, 9, 16]
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   $ python generator_expr.py
        2   <generator object <genexpr> at 0x1004d20a0>
        3   0
        4   1
        5   4
        6   9
        7   16
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   $ python generator.py
       2   <generator object gen_values at 0x1004d2050>
       3   0
       4   1
       5   4
       6   9
       7   16
Errors should never
pass silently.

• Exception-based error
  handling


• Tracebacks aid debugging
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'
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
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
Unless explicitly
silenced.

• Catch exceptions with
  try:except


• Process


• Convert


• Ignore
Catching 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   try:
       9       print f('5')
      10   except TypeError, err:
      11       print 'Had an error:', err
      12   else:
      13       print 'No error'
      14   finally:
      15       print 'Always run'

                  $ python catching.py
                  Had an error: n should be an int
                  Always run
In the face of ambiguity, refuse the temptation to
guess.

• Coerce types only when not
  surprising


• Cannot add strings and
  numbers


• Can multiply them!
Type Coercion

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




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

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




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

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




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

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




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

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




 1   $ python type_coercion.py
 2   5.0
 3   1267650600228229401496703205376
 4   abcabc
 5   Traceback (most recent call last):
 6     File ".../type_coercion.py", line 4, in <module>
 7       print 2 + 'abc'
 8   TypeError: unsupported operand type(s) for +: 'int' and 'str'
There should be one – and
preferably only one – way to
do it.

• Eliminate redundancy


• Easier to learn


• Easier to remember
Index API

   1   a = [ 1, 2, 3 ]
   2   print a[0]
   3
   4   a = (1, 2, 3)
   5   print a[0]             $ python index_api.py
   6                          1
   7   a = 'abc'              1
   8   print a[0]             a
   9                          zero value
  10   a = {0:'zero value',
  11        1:'one value',
  12        }
  13   print a[0]
Although that way may not
be obvious at first unless
you’re Dutch.

• GUI            • Django

  • GTK          • AppEngine

  • KDE          • Pyramid

  • Cocoa        • Flask

  • MS           • TurboGear
    Windows        s

  • Tk           • Pecan

  • wxPython

• Web
Now is better than
never.

• ctypes


• Jython


• IronPython


• Python 2 vs. Python 3
Although never is often
better than right now.

• Language moratorium


• Not everything goes into stdlib
  any more
If the implementation is
hard to explain, it’s a bad    Python Enhancement
                       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!
Closures
Closures


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


       1   def outer(arg):
       2       print 'outer(%s)' % arg
       3
       4       def inner(val):
       5           print 'inner(%s) (arg=%s)' % (val, arg)
       6           return val * arg
       7
       8       return inner                $ python closure.py
       9                                   Creating thrice:
      10   print 'Creating thrice:'        outer(3)
      11   thrice = outer(3)
      12                                   Calling thrice:
      13   print 'nCalling thrice:'       inner(3) (arg=3)
      14   print thrice(3)                 9
      15   print thrice('a')               inner(a) (arg=3)
                                           aaa
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/
Questions?
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/

An Introduction to the Zen of Python

  • 1.
    An Introduction to theZen of Python Doug Hellmann February, 2011
  • 2.
    The Zen ofPython by Tim Peters • Beautiful is better than ugly. • There should be one – and • Explicit is better than implicit. preferably only one – obvious way • Simple is better than complex. to do it. • Complex is better than • Although that way may not be complicated. obvious at first unless you're • Flat is better than nested. Dutch. • Sparse is better than dense. • Now is better than never. • Readability counts. • Although never is often better than • Special cases aren't special *right* now. enough to break the rules. • If the implementation is hard to • Although practicality beats purity. explain, it's a bad idea. • Errors should never pass silently. • If the implementation is easy to • Unless explicitly silenced. explain, it may be a good idea. • In the face of ambiguity, refuse the • Namespaces are one honking temptation to guess. great idea – let's do more of those!
  • 3.
    Beautiful is better thanugly. • Write programs for human readers • Simple expression syntax • Consistent syntax and behavior
  • 4.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 5.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 6.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 7.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 8.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 9.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 10.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 11.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 12.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 13.
    Simple Expressions 1 i = 5 + 5 13 2 14 t = ('a', 1, vals, None) 3 s = 'literal string' 15 t[1] 4 16 5 m = """multi-line 17 d = { 'a':'a value', 6 string 18 'b':'b value', 7 """ 19 } 8 20 d['a'] 9 us = u'üñîçø∂é string' 21 10 22 if a or b: 11 vals = [ 1, 3, 5, 7, ] 23 do_something() 12 vals[0] 24
  • 14.
    Explicit is betterthan implicit. • Boolean type • No “hidden” loop variables • Use “self” to refer to object inside a method
  • 15.
    Boolean Values 1 t = True 2 f = False 3 4 if t: 5 print 't is true' $ python booleans.py 6 t is true 7 if not f: f is false 8 print 'f is false' True 9 False 10 a = t or f 11 b = t and f 12 13 print a 14 print b
  • 16.
    for loops $ python for_loop.py 1 print 'Numbers:' Numbers: 2 0 3 for i in range(5): 1 4 print i 2 5 3 6 print 4 7 print 'Letters:' 8 Letters: 9 for c in [ 'a', 'b', 'c' ]: a 10 print c b c
  • 17.
    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()
  • 18.
    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()
  • 19.
    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()
  • 20.
    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()
  • 21.
    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()
  • 22.
    Simple is betterthan complex. • Garbage collection • print statement • Interactive interpreter for experimentation
  • 23.
    Printing 1 # -*- encoding: utf-8 -*- 2 3 print 'string:', 'string' 4 5 print 'unicode:', u'üñîçø∂é string' 6 7 print 'number:', 5 * 5 8 9 my_list = [ 1, 'a', None ] 10 print 'list:', my_list 11 12 my_dict = { 'a':'a value', 'b':'b value' } 13 print 'dict:', my_dict $ python printing.py string: string unicode: üñîçø∂é string number: 25 list: [1, 'a', None] dict: {'a': 'a value', 'b': 'b value'}
  • 24.
    Printing, with printf-styleFormatting 1 # -*- encoding: utf-8 -*- 2 3 my_list = [ 1, 'a', None ] 4 my_dict = { 'a':'a value', 'b':'b value' } 5 6 args = ('string', u'üñîçø∂é string', 5 * 5, 7 my_list, my_dict) 8 9 print ''' 10 string : %s 11 unicode: %s 12 number : %d $ python printing_with_format.py 13 list : %s 14 dict : %s string : string 15 ''' % args unicode: üñîçø∂é string number : 25 list : [1, 'a', None] dict : {'a': 'a value', 'b': 'b value'}
  • 25.
  • 26.
    Complex is better thancomplicated. • Do complex things in a “Pythonic” way • SciPy and NumPy for advanced science and math
  • 27.
    Interactive Graphic SciPy, NumPy, matplotlib Environment
  • 28.
    NumPy Performance Standard Python NumPy 1 a = range(10000000) 1 import numpy as np 2 b = range(10000000) 2 a = np.arange(10000000) 3 c = [] 3 b = np.arange(10000000) 4 for i in range(len(a)): 4 c = a + b 5 c.append(a[i] + b[i]) 5-10 seconds “nearly instantaneous”
  • 29.
    Flat is betterthan nested. • Wide variety of modules in standard library • Namespace is flat • No need to use long names: com.company.java.blah.blah
  • 30.
    Standard Library Modules:Networking • socket • asyncore • select • asynchat • SocketServer • xmlrpclib • BaseHTTPServer • SimpleXMLRPCServer
  • 31.
    Standard Library Modules:Internet Protocols • urllib • poplib • httplib • imaplib • ftplib • json • smtpd • smtplib
  • 32.
    Standard Library Modules:Command Line • getopt • fileinput • optparse • cmd • argparse • readline
  • 33.
    Standard Library Modules:Parallel Processing • subprocess • multiprocessing • threading • Queue
  • 34.
    Standard Library Modules:Databases • anydbm • shelve • pickle • sqlite3
  • 35.
    Standard Library Modules:Miscellaneous • datetime • struct • grp • ctypes • pwd • xml • profile • tarfile • timeit • csv
  • 36.
    Sparse is betterthan dense. • Standard library stays “shallow” • http://pypi.python.org/ • Allows separate release schedules • pip (“pip installs Python packages”)
  • 37.
    Readability counts. • Whitespacefor block structures • Minimal punctuation • Built-in documentation • Extensive online documentation at http:// docs.python.org/
  • 38.
    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()
  • 39.
    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()
  • 40.
    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()
  • 41.
    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()
  • 42.
    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()
  • 43.
    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()
  • 44.
    Special cases aren’tspecial 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
  • 45.
    String Methods $ python string_methods.py 1 print ' string value '.split() ['string', 'value'] 2 print ' string value '.strip() string value 3 print 'str' in ' string value ' True 4 print 'CHUGALUG'.startswith('C') True 5 print 'CHUGALUG'.endswith('end') False 6 print ':'.join(['a', 'b', 'c']) a:b:c
  • 46.
    String Methods $ python string_methods.py 1 print ' string value '.split() ['string', 'value'] 2 print ' string value '.strip() string value 3 print 'str' in ' string value ' True 4 print 'CHUGALUG'.startswith('C') True 5 print 'CHUGALUG'.endswith('end') False 6 print ':'.join(['a', 'b', 'c']) a:b:c
  • 47.
    String Methods $ python string_methods.py 1 print ' string value '.split() ['string', 'value'] 2 print ' string value '.strip() string value 3 print 'str' in ' string value ' True 4 print 'CHUGALUG'.startswith('C') True 5 print 'CHUGALUG'.endswith('end') False 6 print ':'.join(['a', 'b', 'c']) a:b:c
  • 48.
    String Methods $ python string_methods.py 1 print ' string value '.split() ['string', 'value'] 2 print ' string value '.strip() string value 3 print 'str' in ' string value ' True 4 print 'CHUGALUG'.startswith('C') True 5 print 'CHUGALUG'.endswith('end') False 6 print ':'.join(['a', 'b', 'c']) a:b:c
  • 49.
    String Methods $ python string_methods.py 1 print ' string value '.split() ['string', 'value'] 2 print ' string value '.strip() string value 3 print 'str' in ' string value ' True 4 print 'CHUGALUG'.startswith('C') True 5 print 'CHUGALUG'.endswith('end') False 6 print ':'.join(['a', 'b', 'c']) a:b:c
  • 50.
    String Methods $ python string_methods.py 1 print ' string value '.split() ['string', 'value'] 2 print ' string value '.strip() string value 3 print 'str' in ' string value ' True 4 print 'CHUGALUG'.startswith('C') True 5 print 'CHUGALUG'.endswith('end') False 6 print ':'.join(['a', 'b', 'c']) a:b:c
  • 51.
    String Methods $ python string_methods.py 1 print ' string value '.split() ['string', 'value'] 2 print ' string value '.strip() string value 3 print 'str' in ' string value ' True 4 print 'CHUGALUG'.startswith('C') True 5 print 'CHUGALUG'.endswith('end') False 6 print ':'.join(['a', 'b', 'c']) a:b:c
  • 52.
    Function and MethodScope 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
  • 53.
    Dynamic Attribute Lookup 1 class MyClass(object): 2 3 CLASS_ATTR = 'class value' 4 5 def __init__(self, arg): 6 self.attr = arg 7 8 o = MyClass('instance value') 9 print o.attr 10 print o.CLASS_ATTR $ python dynamic_attribute_lookup.py instance value class value
  • 54.
    Dynamic Typing 1 class A(object): 2 def do_something(self): 3 print 'in A' 4 5 class B(object): $ python dynamic_typing.py 6 def do_something(self): in A 7 print 'in B' in B 8 9 def work_on_obj(c): 10 c.do_something() 11 12 a = A() 13 b = B() 14 15 work_on_obj(a) 16 work_on_obj(b)
  • 55.
    Regular Expressions 1 import re 2 3 pattern = 'this' 4 text = 'Does this text match the pattern?' 5 6 match = re.search(pattern, text) 7 8 s = match.start() 9 e = match.end() 10 11 print 'Found :', match.re.pattern 12 print 'In :', match.string 13 print 'Range :', s, '-', e 14 print 'Substring:', text[s:e] $ python using_regex.py Found : this In : Does this text match the pattern? Range : 5 - 9 Substring: this
  • 56.
    Although practicality beats purity. •Multiple Programming Models • OOP • Procedural • Functional
  • 57.
    Procedural 1 def my_function(arg1, arg2): 2 """This function multiplies arg1 by arg2. 3 """ 4 return arg1 * arg2 5 6 results = [] 7 for i in range(5): 8 results.append(my_function(i, i)) 9 10 print results $ python procedural.py [0, 1, 4, 9, 16]
  • 58.
    Functional: List Comprehension 1 results = [ i*i for i in range(5) ] 2 3 print results $ python functional.py [0, 1, 4, 9, 16]
  • 59.
    Functional: List Comprehension 1 results = [ i*i for i in range(5) ] 2 3 print results $ python functional.py [0, 1, 4, 9, 16]
  • 60.
    Functional: List Comprehension 1 results = [ i*i for i in range(5) ] 2 3 print results $ python functional.py [0, 1, 4, 9, 16]
  • 61.
    Functional: List Comprehension 1 results = [ i*i for i in range(5) ] 2 3 print results $ python functional.py [0, 1, 4, 9, 16]
  • 62.
    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 $ python generator_expr.py 2 <generator object <genexpr> at 0x1004d20a0> 3 0 4 1 5 4 6 9 7 16
  • 63.
    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 $ python generator.py 2 <generator object gen_values at 0x1004d2050> 3 0 4 1 5 4 6 9 7 16
  • 64.
    Errors should never passsilently. • Exception-based error handling • Tracebacks aid debugging
  • 65.
    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'
  • 66.
    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
  • 67.
    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
  • 68.
    Unless explicitly silenced. • Catchexceptions with try:except • Process • Convert • Ignore
  • 69.
    Catching 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 try: 9 print f('5') 10 except TypeError, err: 11 print 'Had an error:', err 12 else: 13 print 'No error' 14 finally: 15 print 'Always run' $ python catching.py Had an error: n should be an int Always run
  • 70.
    In the faceof ambiguity, refuse the temptation to guess. • Coerce types only when not surprising • Cannot add strings and numbers • Can multiply them!
  • 71.
    Type Coercion 1 print 5 * 1.0 2 print 2 ** 100 3 print 2 * 'abc' 4 print 2 + 'abc' 1 $ python type_coercion.py 2 5.0 3 1267650600228229401496703205376 4 abcabc 5 Traceback (most recent call last): 6 File ".../type_coercion.py", line 4, in <module> 7 print 2 + 'abc' 8 TypeError: unsupported operand type(s) for +: 'int' and 'str'
  • 72.
    Type Coercion 1 print 5 * 1.0 2 print 2 ** 100 3 print 2 * 'abc' 4 print 2 + 'abc' 1 $ python type_coercion.py 2 5.0 3 1267650600228229401496703205376 4 abcabc 5 Traceback (most recent call last): 6 File ".../type_coercion.py", line 4, in <module> 7 print 2 + 'abc' 8 TypeError: unsupported operand type(s) for +: 'int' and 'str'
  • 73.
    Type Coercion 1 print 5 * 1.0 2 print 2 ** 100 3 print 2 * 'abc' 4 print 2 + 'abc' 1 $ python type_coercion.py 2 5.0 3 1267650600228229401496703205376 4 abcabc 5 Traceback (most recent call last): 6 File ".../type_coercion.py", line 4, in <module> 7 print 2 + 'abc' 8 TypeError: unsupported operand type(s) for +: 'int' and 'str'
  • 74.
    Type Coercion 1 print 5 * 1.0 2 print 2 ** 100 3 print 2 * 'abc' 4 print 2 + 'abc' 1 $ python type_coercion.py 2 5.0 3 1267650600228229401496703205376 4 abcabc 5 Traceback (most recent call last): 6 File ".../type_coercion.py", line 4, in <module> 7 print 2 + 'abc' 8 TypeError: unsupported operand type(s) for +: 'int' and 'str'
  • 75.
    Type Coercion 1 print 5 * 1.0 2 print 2 ** 100 3 print 2 * 'abc' 4 print 2 + 'abc' 1 $ python type_coercion.py 2 5.0 3 1267650600228229401496703205376 4 abcabc 5 Traceback (most recent call last): 6 File ".../type_coercion.py", line 4, in <module> 7 print 2 + 'abc' 8 TypeError: unsupported operand type(s) for +: 'int' and 'str'
  • 76.
    There should beone – and preferably only one – way to do it. • Eliminate redundancy • Easier to learn • Easier to remember
  • 77.
    Index API 1 a = [ 1, 2, 3 ] 2 print a[0] 3 4 a = (1, 2, 3) 5 print a[0] $ python index_api.py 6 1 7 a = 'abc' 1 8 print a[0] a 9 zero value 10 a = {0:'zero value', 11 1:'one value', 12 } 13 print a[0]
  • 78.
    Although that waymay not be obvious at first unless you’re Dutch. • GUI • Django • GTK • AppEngine • KDE • Pyramid • Cocoa • Flask • MS • TurboGear Windows s • Tk • Pecan • wxPython • Web
  • 79.
    Now is betterthan never. • ctypes • Jython • IronPython • Python 2 vs. Python 3
  • 80.
    Although never isoften better than right now. • Language moratorium • Not everything goes into stdlib any more
  • 81.
    If the implementationis hard to explain, it’s a bad Python Enhancement idea.
  • 82.
    If the implementationis easy to explain, it may be a good idea.
  • 83.
    Namespaces are one honkinggreat idea – let’s do more of those! Closures
  • 84.
    Closures 1 def outer(arg): 2 print 'outer(%s)' % arg 3 4 def inner(val): 5 print 'inner(%s) (arg=%s)' % (val, arg) 6 return val * arg 7 8 return inner 9 10 print 'Creating thrice:' 11 thrice = outer(3) 12 13 print 'nCalling thrice:' 14 print thrice(3) 15 print thrice('a')
  • 85.
    Closures 1 def outer(arg): 2 print 'outer(%s)' % arg 3 4 def inner(val): 5 print 'inner(%s) (arg=%s)' % (val, arg) 6 return val * arg 7 8 return inner $ python closure.py 9 Creating thrice: 10 print 'Creating thrice:' outer(3) 11 thrice = outer(3) 12 Calling thrice: 13 print 'nCalling thrice:' inner(3) (arg=3) 14 print thrice(3) 9 15 print thrice('a') inner(a) (arg=3) aaa
  • 86.
    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/
  • 87.
  • 88.
    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/