TYPES 25 For user-defined classes, str and repr can be defined/redefined using the special operators str and repr . These are briefly described later on; for more, refer to the official Python documentation [38]. repr always has a default value. Another important characteristic of a Python string is that, like a list, it is an iterable object. 1 >>> for i in 'hello': 2 print i 3 h 4 e 5 l 6 l 7 o list The main methods of a Python list are append, insert, and delete: 1 >>> a = [1, 2, 3] 2 >>> print type(a) 3 <type 'list'> 4 >>> a.append(8) 5 >>> a.insert(2, 7) 6 >>> del a[0] 7 >>> print a 8 [2, 7, 3, 8] 9 >>> print len(a) 10 4 Lists can be sliced: 1 >>> print a[:3] 2 [2, 7, 3] 3 >>> print a[1:] 4 [7, 3, 8] 5 >>> print a[-2:] 6 [3, 8] and concatenated: 1 >>> a = [2, 3] 2 >>> b = [5, 6] 3 >>> print a + b 4 [2, 3, 5, 6] A list is iterable; you can loop over it: 1 >>> a = [1, 2, 3] 2 >>> for i in a: 3 print i 4 1 5 2 6 3 26 THE PYTHON LANGUAGE The elements of a list do not have to be of the same type; they can be any type of Python object. tuple A tuple is like a list, but its size and elements are immutable, while in a list they are mutable. If a tuple element is an object, the object attributes are mutable. A tuple is delimited by round brackets. 1 >>> a = (1, 2, 3) So while this works for a list: 1 >>> a = [1, 2, 3] 2 >>> a[1] = 5 3 >>> print a 4 [1, 5, 3] the element assignment does not work for a tuple: 1 >>> a = (1, 2, 3) 2 >>> print a[1] 3 2 4 >>> a[1] = 5 5 Traceback (most recent call last): 6 File "<stdin>", line 1, in <module> 7 TypeError: 'tuple' object does not support item assignment The tuple, like the list, is an iterable object. Notice that a tuple consisting of a single element must include a trailing comma, as shown below: 1 >>> a = (1) 2 >>> print type(a) 3 <type 'int'> 4 >>> a = (1,) 5 >>> print type(a) 6 <type 'tuple'> Tuples are very useful for efficient packing of objects because of their immutability, and the brackets are often optional: 1 >>> a = 2, 3, 'hello' 2 >>> x, y, z = a 3 >>> print x 4 2 5 >>> print z 6 hello dict A Python dictionary is a hash table that maps a key object to a value object. For example: TYPES 27 1 >>> a = {'k':'v', 'k2':3} 2 >>> a['k'] 3 v 4 >>> a['k2'] 5 3 6 >>> a.has_key('k') 7 True 8 >>> a.has_key('v') 9 False Keys can be of any hashable type (int, string, or any object whose class implements the hash method). Values can be of any type. Different keys and values in the same dictionary do not have to be of the same type. If the keys are alphanumeric characters, a dictionary can also be declared with the alternative syntax: 1 >>> a = dict(k='v', h2=3) 2 >>> a['k'] 3 v 4 >>> print a 5 {'k':'v', 'h2':3} Useful methods are has key, keys, values and items: 1 >>> a = dict(k='v', k2='3) 2 >>> print a.keys() 3 ['k', 'k2'] 4 >>> print a.values() 5 ['v', 3] 6 >>> print a.items() 7 [('k', 'v'), ('k2', 3)] The items method produces a list of tuples, each containing a key and its associated value. Dictionary elements and list elements can be deleted with the command del: 1 >>> a = [1, 2, 3] 2 >>> del a[1] 3 >>> print a 4 [1, 3] 5 >>> a = dict(k='v', h2=3) 6 >>> del a['h2'] 7 >>> print a 8 {'k':'v'} Internally, Python uses the hash operator to convert objects into integers, and uses that integer to determine where to store the value. 1 >>> hash("hello world") 2 -1500746465 28 THE PYTHON LANGUAGE 2.5 About Indentation Python uses indentation to delimit blocks of code. A block starts with a line ending in colon, and continues for all lines that have a similar or higher indentation as the next line. For example: 1 >>> i = 0 2 >>> while i < 3: 3 >>> print i 4 >>> i = i + 1 5 >>> 6 0 7 1 8 2 It is common to use 4 spaces for each level of indentation. It is a good policy not to mix tabs with spaces, or you may run into trouble. 2.6 for in In Python, you can loop over iterable objects: 1 >>> a = [0, 1, 'hello', 'python'] 2 >>> for i in a: 3 print i 4 0 5 1 6 hello 7 python One common shortcut is xrange, which generates an iterable range without storing the entire list of elements. 1 >>> for i in xrange(0, 4): 2 print i 3 0 4 1 5 2 6 4 This is equivalent to the C/C++/C#/Java syntax: 1 for(int i=0; i<4; i=i+1) { print(i); } Another useful command is enumerate, which counts while looping: 1 >>> a = [0, 1, 'hello', 'python'] 2 >>> for i, j in enumerate(a): 3 print i, j 4 0 0 5 1 1 6 2 hello 7 3 python WHILE 29 There isalsoakeywordrange(a, b, c) thatreturnsalistofintegersstarting with the value a, incrementing by c, and ending with the last value smaller than b, a defaults to 0 and c defaults to 1. xrange is similar but does not actually generate the list, only an iterator over the list; thus it is better for looping. You can jump out of a loop using break 1 >>> for i in [1, 2, 3]: 2 print i 3 break 4 1 You can jump to the next loop iteration without executing the entire code block with continue 1 >>> for i in [1, 2, 3]: 2 print i 3 continue 4 print 'test' 5 1 6 2 7 3 2.7 while The while loop in Python works much as it does in many other programming languages, by looping an indefinite number of times and testing a condition before each iteration. If the condition is False, the loop ends. 1 >>> i = 0 2 >>> while i < 10: 3 i = i + 1 4 >>> print i 5 10 There is no loop until construct in Python. 2.8 def return Here is a typical Python function: 1 >>> def f(a, b=2): 2 return a + b 3 >>> print f(4) 4 6 30 THE PYTHON LANGUAGE There is no need (or way) to specify types of the arguments or the return type(s). Function argumentscanhavedefaultvaluesandcanreturnmultipleobjects: 1 >>> def f(a, b=2): 2 return a + b, a - b 3 >>> x, y = f(5) 4 >>> print x 5 7 6 >>> print y 7 3 Function arguments can be passed explicitly by name: 1 >>> def f(a, b=2): 2 return a + b, a - b 3 >>> x, y = f(b=5, a=2) 4 >>> print x 5 7 6 >>> print y 7 -3 Functions can take a variable number of arguments: 1 >>> def f( * a, ** b): 2 return a, b 3 >>> x, y = f(3, 'hello', c=4, test='world') 4 >>> print x 5 (3, 'hello') 6 >>> print y 7 {'c':4, 'test':'world'} Here arguments not passed by name (3, ’hello’) are stored in list a, and arguments passed by name (c and test) are stored in the dictionary b. In the opposite case, a list or tuple can be passed to a function that requires individual positional arguments by unpacking them: 1 >>> def f(a, b): 2 return a + b 3 >>> c = (1, 2) 4 >>> print f( * c) 5 3 and a dictionary can be unpacked to deliver keyword arguments: 1 >>> def f(a, b): 2 return a + b 3 >>> c = {'a':1, 'b':2} 4 >>> print f( ** c) 5 3 IF ELIF ELSE 31 2.9 if elif else The use of conditionals in Python is intuitive: 1 >>> for i in range(3): 2 >>> if i == 0: 3 >>> print 'zero' 4 >>> elif i == 1: 5 >>> print 'one' 6 >>> else: 7 >>> print 'other' 8 zero 9 one 10 other "elif" means "else if". Both elif and else clauses are optional. There can be more than one elif but only one else statement. Complex conditions can be created using the not, and and or operators. 1 >>> for i in range(3): 2 >>> if i == 0 or (i == 1 and i + 1 == 2): 3 >>> print '0 or 1' 2.10 try except else finally Python can throw - pardon, raise - Exceptions: 1 >>> try: 2 >>> a = 1 / 0 3 >>> except Exception, e 4 >>> print 'error', e, 'occurred' 5 >>> else: 6 >>> print 'no problem here' 7 >>> finally: 8 >>> print 'done' 9 error 3 occurred 10 done If the exception is raised, it is caught by the except clause, which is executed, while the else clause is not. If no exception is raised, the except clause is not executed, but the else one is. The finally clause is always executed. There can be multiple except clauses for different possible exceptions: 1 >>> try: 2 >>> raise SyntaxError 3 >>> except ValueError: 4 >>> print 'value error' 5 >>> except SyntaxError: 6 >>> print 'syntax error' 7 syntax error 32 THE PYTHON LANGUAGE The else and finally clauses are optional. Here is a list of built-in Python exceptions + HTTP (defined by web2py) 1 BaseException 2 + HTTP (defined by web2py) 3 + SystemExit 4 + KeyboardInterrupt 5 + Exception 6 + GeneratorExit 7 + StopIteration 8 + StandardError 9 | + ArithmeticError 10 | | + FloatingPointError 11 | | + OverflowError 12 | | + ZeroDivisionError 13 | + AssertionError 14 | + AttributeError 15 | + EnvironmentError 16 | | + IOError 17 | | + OSError 18 | | + WindowsError (Windows) 19 | | + VMSError (VMS) 20 | + EOFError 21 | + ImportError 22 | + LookupError 23 | | + IndexError 24 | | + KeyError 25 | + MemoryError 26 | + NameError 27 | | + UnboundLocalError 28 | + ReferenceError 29 | + RuntimeError 30 | | + NotImplementedError 31 | + SyntaxError 32 | | + IndentationError 33 | | + TabError 34 | + SystemError 35 | + TypeError 36 | + ValueError 37 | | + UnicodeError 38 | | + UnicodeDecodeError 39 | | + UnicodeEncodeError 40 | | + UnicodeTranslateError 41 + Warning 42 + DeprecationWarning 43 + PendingDeprecationWarning 44 + RuntimeWarning 45 + SyntaxWarning 46 + UserWarning 47 + FutureWarning 48 + ImportWarning 49 + UnicodeWarning For a detailed description of each of them, refer to the official Python documentation. CLASS 33 web2py exposes only one new exception, called HTTP. When raised, it causes the program to return an HTTP error page (for more on this refer to Chapter 4). Any object can be raised as an exception, but it is good practice to raise objects that extend one of the built-in exceptions. 2.11 class Because Python is dynamically typed, Python classes and objects may seem odd. In fact, you do not need to define the member variables (attributes) when declaring a class, and different instances of the same class can have different attributes. Attributes are generally associated with the instance, not the class (except when declared as "class attributes", which is the same as "static member variables" in C++/Java). Here is an example: 1 >>> class MyClass(object): pass 2 >>> myinstance = MyClass() 3 >>> myinstance.myvariable = 3 4 >>> print myinstance.myvariable 5 3 Notice that pass is a do-nothing command. In this case it is used to define a class MyClass that contains nothing. MyClass() calls the constructor of the class (in this case the default constructor) and returns an object, an instance of the class. The (object) in the class definition indicates that our class extends the built-in object class. This is not required, but it is good practice. Here is a more complex class: 1 >>> class MyClass(object): 2 >>> z = 2 3 >>> def __init__(self, a, b): 4 >>> self.x = a, self.y = b 5 >>> def add(self): 6 >>> return self.x + self.y + self.z 7 >>> myinstance = MyClass(3, 4) 8 >>> print myinstance.add() 9 9 Functions declared inside the class are methods. Some methods have special reserved names. For example, init is the constructor. All variables are local variables of the method except variables declared outside methods. For example, z is a class variable, equivalent to a C++ static member variable that holds the same value for all instances of the class. Notice that init takes 3 arguments and add takes one, and yet we call them with 2 and 0 arguments respectively. The first argument represents, 34 THE PYTHON LANGUAGE by convention, the local name used inside the method to refer to the current object. Here we use self to refer to the current object, but we could have used any other name. self plays the same role as * this in C++ or this in Java, but self is not a reserved keyword. This syntax is necessary to avoid ambiguity when declaring nested classes, such as a class that is local to a method inside another class. 2.12 Special Attributes, Methods and Operators Class attributes, methods, and operators starting with a double underscore are usually intended to be private, although this is a convention that is not enforced by the interpreter. Some of them are reserved keywords and have a special meaning. Here, as an example, are three of them: • len • getitem • setitem They can be used, for example, to create a container object that acts like a list: 1 >>> class MyList(object) 2 >>> def __init__(self, * a): self.a = a 3 >>> def __len__(self): return len(self.a) 4 >>> def __getitem__(self, i): return self.a[i] 5 >>> def __setitem__(self, i, j): self.a[i] = j 6 >>> b = MyList(3, 4, 5) 7 >>> print b[1] 8 4 9 >>> a[1] = 7 10 >>> print b.a 11 [3, 7, 5] Other special operators include getattr and setattr , which define the get and set attributes for the class, and sum and sub , which overload arithmetic operators. For the use of these operators we refer the reader to more advanced books on this topic. We have already mentioned the special operators str and repr . 2.13 File Input/Output In Python you can open and write in a file with: . dict(k='v', k2='3) 2 >>> print a.keys() 3 ['k', 'k2'] 4 >>> print a.values() 5 ['v', 3] 6 >>> print a.items() 7 [('k',. x, y = f(3, 'hello', c=4, test='world') 4 >>> print x 5 (3, 'hello') 6 >>> print y 7 {'c':4, 'test':'world'} Here arguments. built-in Python exceptions + HTTP (defined by web2 py) 1 BaseException 2 + HTTP (defined by web2 py) 3 + SystemExit 4 + KeyboardInterrupt 5 + Exception 6 + GeneratorExit 7 + StopIteration 8 + StandardError 9