Presentation is loading. Please wait.

Presentation is loading. Please wait.

Python Programming Language

Similar presentations


Presentation on theme: "Python Programming Language"— Presentation transcript:

1 Python Programming Language

2 First up: An Introduction to Python
who uses it? what is it?

3 From the Python website
Python is being used by Nasa, Rackspace, Industrial Light and Magic, AstraZeneca, Honeywell, Google: “Python has been an important part of Google since the beginning, and remains so as the system grows and evolves. Today dozens of Google engineers use Python, and we're looking for more people with skills in this language." said Peter Norvig, Director of Research at Google. Many Python success stories:

4 Python dynamic - no static typing (uses duck/latent typing)‏
code is interpreted dynamic name resolution – binds methods and names at runtime (determines what a name refers to at runtime)‏ object-oriented – ability to create objects, inheritance, polymorphism minimalist – there should only be one obvious way to do something fun to use (named after Monty Python's Flying Circus)‏

5 Python very high-level programming language – high level data types built-in (such as dictionaries)‏ program can be split into modules that can be used in other programs lots of modules available (standard library) – file I/O, system calls, GUI development, HTML/XHTML processing, interprocess communication and more provides support for working with other languages

6 Next: Python interpreter
where is it? how to start it? Interactive mode non-interactive mode

7 Python Interpreter On Linux/Unix machines, python normally installed at: /usr/local/bin/python make sure /usr/local/bin is on your path for tcsh, csh, add this to your .cshrc file set PATH = ($PATH /usr/local/bin)‏ for bash, add this to your .bashrc file export PATH=$PATH:/usr/local/bin On windows machine, python normally installed at: C:\Python25 add this to your path, by typing what is below at the DOS prompt set path=%path%;C:\python25

8 Python interpeter If Python is on your path, you can get into the interactive interpreter by typing: python Exit the interpreter by ctrl-Z on windows ctrl-D on Unix/Linux import sys; sys.exit();

9 Python Interactive Interpreter
Start up Python interpreter and it acts much like a shell program, waiting for user to type in commands (student)~/classes/5530/Python% python Python (#1, Jun , 09:06:31)‏ [GCC (Red Hat )] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> a = "cat " >>> b = 2 >>> a * b 'cat cat ' >>>

10 Interactive mode Interactive mode prompts
>>> indicates python is waiting for user input indicates python is waiting for the continuation of user input (multi-line command)‏ the absence of >>> or ... is program output >>> for i in [1, 2, 3]: print i ... 1 2 3 >>>

11 Non-interactive mode Provide python with name of module
(student)~/classes/5530/Python% more hello.py print "hello" (student)~/classes/5530/Python% python hello.py hello (student)~/classes/5530/Python%

12 Non-interactive mode On linux/unix machines
give module execute permissions chmod a+x hello.py add path to python as first line in the module file using Unix shebang notation (student)~/classes/5530/Python% more hello.py #!/usr/local/bin/python print "hello" (student)~/classes/5530/Python% hello.py hello

13 Non-interactive mode Can execute a module and then get into interactive mode by including -i option before the module name (student)~/classes/5530/Python% python -i hello.py hello >>> print "hello"

14 Next: formatting Python programs
comments line joining indentation (yes, it really counts)‏

15 Comments begin with a #

16 Explicit line joining A backlash \ can be used to join physically separate lines into a single logical line >>> str = "hello \ ... world" >>> str 'hello world' >>> a = 20 >>> b = 10 >>> if (a > b & \ ... b < 15): ... print "a", a, "b", b ... a 20 b 10 >>>

17 Implicit line joining expressions in parentheses, square brackets, curly braces can be split over multiple lines without a \ >>> if (a > b ... & b < 15): print "a", a, "b", b ... a 20 b 10 >>>

18 Indentation Indentation (not braces or begin/end) is used to indicate the grouping of statements tabs are replaced by spaces and the total number of spaces is used to determine the indentation level of the line don't mix spaces and tabs in your indentation scheme

19 Correctly, but sloppily, indented code
#!/usr/local/bin/python def factorial(n): result = 1 if (n == 0): return 1 if (n < 0): return "invalid input" while (n > 1): result = result * n #these two statements must n = n #be indented same amount return result i = input("Enter a positive integer> ")‏ print "The factorial of", i, "is", factorial(i)‏

20 Incorrectly indented code
#!/usr/local/bin/python def factorial(n): result = 1 if (n == 0): return 1 if (n < 0): return "invalid input" while (n > 1): result = result * n n = n #should be indented same as above return result #should be indented same as while i = input("Enter a positive integer> ")‏ print "The factorial of", i, "is", factorial(i)‏

21 Next: Python identifiers
What's in a name?

22 Python identifiers may begin with a letter or an underscore which may be followed by any sequence of letters, digits, or underscores some words are reserved: and, as, assert, break, class, continue, def, del, elif, else except, exec, finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, while, with, yield

23 Python names (variables)‏
Like Ruby (and unlike C, C++, Java), there is no primitive type in Python – everything is an object Variables are references to objects; python resources often call them names (names for objects) instead of variables dynamic garbage collection is performed to reclaim space used by non-referenced objects

24 Next: Python I/O print statement input and raw_input

25 print statement evaluates and prints expressions separated by commas left to right prints a space between each expression doesn't print newline if comma at end (student)~/classes/5530/Python% python Python (#1, Jun , 09:06:31)‏ [GCC (Red Hat )] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> a = 3 >>> print "hello there", a + 4, 3 * 5 hello there 7 15 >>>

26 input statement displays a prompt, evaluates and returns expression from standard input >>> input("Enter an expression> ")‏ Enter an expression> 3 * 4 12 >>> ans = input("Enter an expression> ")‏ Enter an expression> 3 * 4 + 1 >>> ans 13 >>> input("Enter a string> ")‏ Enter a string> hello Traceback (most recent call last): File "<stdin>", line 1, in ? File "<string>", line 0, in ? NameError: name 'hello' is not defined

27 input statement Since the input statement evaluates the expression entered, unquoted strings are treated as variables >>> hello = "goodbye" >>> input("Enter a string> ")‏ Enter a string> hello 'goodbye' >>>

28 raw_input statement displays a prompt and reads and returns an expression from standard input (without evaluation)‏ >>> str = raw_input("Enter an expression> ")‏ Enter an expression> 3 * 4 + 5 >>> str '3 * 4 + 5' >>> str = raw_input("Enter your name> ")‏ Enter your name> Cindy Norris 'Cindy Norris'

29 Next: Python numeric data types
the types: integer, float, long integer, complex operators functions Math library

30 Numeric Data Types integer – 32 bit, two's complement
float – 64 bit double precision long integer – arbitrarily large integer complex – real and imaginary part written as 3 + 2j or j

31 Integer Data Type integer constants specified with or without a sign
default is decimal, but hex and octal constants can be specified long integer constants created by providing an L (or l) at the end of the integer constant like Ruby, a long integer data object is automatically created when an integer object is too small

32 Integer Data Type >>> a = 3
>>> type(a) # returns type of object <type 'int'> >>> a = 3L # create a Long object >>> type(a)‏ <type 'long'> >>> a = 0x15 # hex constant (creates integer object)‏ >>> a 21 >>> a = # octal constant 15 >>> a = 017l # octal constant (Long)‏

33 (student)~/classes/5530/Python% more fact.py
#!/usr/local/bin/python def factorial(n): result = 1 while (n > 1): result = result * n n = n - 1 return result i = input("Enter a positive integer> ")‏ print "The factorial of", i, "is", factorial(i)‏ (student)~/classes/5530/Python% fact.py Enter a positive integer> 5 The factorial of 5 is 120 Enter a positive integer> 9 The factorial of 9 is Enter a positive integer> 15 The factorial of 15 is

34 Numeric operators/functions
addition subtraction * multiplication / division ** exponentiation % modulus -, unary -, unary + <<, >> left shift, right shift &, |, ^ bitwise and, or, exclusive or abs() absolute value

35 Comparison operators a < b true if a is less than b
a <= b true if a is less than or equal to b a == b true if a is equal to b a >= b true if a is greater than or equal to b a > b true if a is greater than b a <> b true if a not equal to b a != b true if a not equal to b These operators can be used on strings, lists, tuples also

36 Boolean operators a and b evaluates to true if both a and b are
true. b not evaluated if a is false a or b evaluates to true if either a is true b is true. b not evaluated if a is true not a evaluates to true if a is false Like C, 0 is false and non-zero is true. These operators can be used on strings, lists, and tuples. An empty string/list/tuple is false.

37 Principal numeric functions
abs(x)‏ cmp(x, y) – compares x and y, returns number greater than (less than, equal to) zero when x is greater (less than, equal to) y divmod(i, j) – returns tuple (i / j, i % j)‏ float(x) – converts string or number x to floating point int(x [, radix]) – converts string or number to an integer using radix (if specified); if radix given, x must be a string

38 Principle numeric functions
long(x[, radix]) – converts string or number to long min(seq) – returns minimum value in a sequence min(a, b, c, ...) - returns the minimum argument max(seq), max(a, b, c, ...)‏ pow(x, y[, z]) – returns x to the power y [modulo z] round(x[, n]) – round x to n decimal places; 0 places if n is omitted

39 Math library standard mathematics library provides routines to compute trigonometric functions, logarithms, etc. these can be found on-line, numerous places, try: >>> import math >>> math.pi >>> math.ceil(3.3)‏ 4.0

40 Next, sequence types what are they? Strings: literals, operators, methods, formatting Lists: construction, operators, methods, functions Tuples Ranges

41 Sequence types The sequence types of Python include: string, list, tuple, xrange/range Most sequence types support the operations: in not in + (concatenation)‏ * (repetition)‏

42 String literals sequence of characters enclosed in single quotes or double quotes (use double quotes if your string includes single quotes and vice versa)‏ strings can contain escape sequences for newlines, tabs, etc. >>> str ='hello\nthere\tworld' >>> str 'hello\nthere\tworld' >>> print str hello there world >>>

43 Raw string literals If the string literal is preceded by an r then it is a raw string escape characters are not converted, but newlines in the source do represent newlines >>> str = r"hello\nthere\ ... world" >>> str 'hello\\nthere\\\nworld' >>> print str hello\nthere\ world <- \ required for continuation <- but also becomes part of <- string

44 Triple quoted strings end of lines in the source, as well as escape sequences, are part of triple quoted strings >>> str = ''' ... hello\nthere ... world ... ''' >>> str '\nhello\nthere\nworld\n' >>> print str hello there world >>> >>> str="""hello\ ... there\nworld ... """ >>> str 'hellothere\nworld\n' >>> print str hellothere world >>> <- \ character <- means newline <- not included

45 Escape sequences in string literals
\newline ignored: allows continuation \\ backslash \' single quote \” double quote \a ASCII bell \b ASCII backspace \f ASCII form feed \n ASCII line feed \r ASCII carriage return \t ASCII horizontal tab \v ASCII vertical tab \0oo ASCII character with octal value oo \xhh ASCII character with hex value hh

46 String indexing strings can be subscripted (indexed) like they can in C a negative index can be used to access a string from the right hand side >>> str = "CS 5530" >>> str[0] 'C' >>> str[-1] '0' >>> str[-2] '3' >>>

47 String slicing slicing provides a substring from a string
str[start:end] returns substring beginning at start up through, but not including, end str[s:e:step] returns substring beginning at s up through e, incrementing by step >>> str = "CS 5530" >>> str[1:4] #characters 1 through 3 'S 5' >>> str[:4] #characters 0 through 3 'CS 5' >>> str[2:] #characters 2 through last ' 5530' >>> str[:] #entire string 'CS 5530'

48 String operations/functions
string concatenation * string repetition len(<string>) returns string length for <var> in <string> iterates through chars ord(<string>) returns ascii code of a string of length 1 chr(<num>) returns string of length 1 whose ascii code is <num> int(<str>) converts string to int

49 String functions hex(x) – returns string containing hex representation of x where x is an integer or long oct(x) – returns string containing oct representation of x repr(s) – returns string representation of s where s can be of any type

50 String operations/functions
>>> ord("a")‏ 97 >>> chr(97)‏ 'a' >>> int("236")‏ 236 >>> len("hello")‏ 5 >>> long("236")‏ 236L >>> int("23F", 16)‏ 575 >>> str = "hello world" >>> str[0:len(str)-1:2] 'hlowr' >>> str = "bye" >>> str = "good " + str >>> str 'good bye' >>> str = (str + ", ") * 2 'good bye, good bye, ' >>> str = str[0:(len(str) - 2)] 'good bye, good bye' >>> "a" in "bac" True >>> "a" not in "bac" False

51 String comparions can compare strings with the operators ==, <, >, <=, >=, != >>> "apple" == "apple" True >>> "apple" < "banana" >>> "apple" <= "banana" >>> "apple" > "banana" False >>> "apple" >= "banana" >>> "apple" != "banana"

52 String methods s.capitalize() - returns copy of s with first letter capitalized s.lower() - returns copy of s with first letter in lower case s.swapcase() - returns a copy of s in which the character case of each letter has been switched s.title() - returns a copy of s in which all words start with uppercase and all other characters are lower case

53 String Methods s.upper() - returns a copy of s converted to uppercase
s.isalpha() - returns True if all characters alphabetic s.isalnum() - returns True if all characters are alphanumeric s.isdigit() - returns True if all characters are digits s.islower() - returns True if all characters are lowercase

54 String methods s.isspace() - returns True if s is only whitespace
s.istitle() - returns True if s is titlecased s.isupper() - returns True if all cased characters are uppercase s.count(sub [, start[,end]]) – returns the number of non-overlapping occurrence of the string sub in s s.startswith(sub [, start[, end]]) – returns True if the indicated part of s starts with the string sub

55 String methods s.endswith(sub [, start[, end]])‏
s.find(sub [, start[, end]]) – returns the leftmost index in the indicated portion of the string s of the string sub; returns -1 if sub not found s.index(sub [, start[, end]]) – like find but introduces an IndexError exception if sub not found s.rfind(sub [, start[, end]]) – like find, but finds rightmost occurrence s.rindex(sub [, start[, end]]) – like rfind but can introduce IndexError exception

56 String methods s.expandtabs([tabsize]) – returns a copy of s with tabs replaced by tabsize (default 8) spaces s.lstrip() - returns a copy of s with leading whitespace removed s.replace(old, new[, maxsplit]) – returns a copy of s with old replaced by new a maximum of maxsplit times s.rstrip() - returns a copy of s with trailing whitespace removed s.strip() - strips leading and trailing whitespace

57 String methods s.translate(table [, deletechars]) – returns a copy of s where all characters in deletechars have been removed and all others have been translated using table (uses maketrans function to create translate table)‏ s.split([sep [, maxsplit]]) – return a list of strings between the occurrences of sep (default whitespace)‏ s.join(seq) – return a string formed by concatenating the strings in the sequence seq

58 String methods More than listed on these slides is available
here's one web source: >>> str = 'good bye, good bye' >>> str.capitalize()‏ 'Good bye, good bye' >>> str.center(20)‏ ' good bye, good bye ' >>> str.count('bye')‏ 2 >>> str.split()‏ ['good', 'bye,', 'good', 'bye']

59 String formatting operations
if the string contains a % then the format following the % is replaced by a value specified following the string if the string contains multiple % format fields, then the % after the string must be followed by a tuple >>> a = 3 >>> print "the value of a is %03d " % a the value of a is 003 >>> a = 3 >>> b = 4 >>> print "the values of a and b are %d and %d" % (a, b)‏

60 What the format consists of
% marks the beginning mapping key in parentheses consisting of a name used as an index into a dictionary (optional)‏ conversion flags (optional)‏ minimum field length (optional)‏ precision given as a . followed by the field length (optional)‏ length modifier (optional)‏ conversion type

61 Conversion flags # conversion will use “alternate form”
(specific meaning depends upon conversion type)‏ numeric values are zero padded converted value is left justified space blank before a positive number sign placed before the conversion

62 Conversion Types d, i signed integer u unsigned integer
o unsigned octal x, X unsigned hex e, E floating point exponential format f, F floating point decimal format g, G either floating point or decimal format depending upon precision c character r, s string % results in % being displayed

63 Examples >>> print "%2d" % 23 23
>>> print "%5.2f" % 23.48 >>> print "%g" % 100299 >>> print "%g" % 1.003e+06 >>> print "hello %10s" % "CS 5530" hello CS 5530 >>> print "hello %s" % "CS 5530" hello CS 5530 >>> print "hello %-10s" % "CS 5530"

64 Examples more info: http://docs.python.org/lib/typesseq-strings.html
>>> str = "the value of a is %f" % a >>> str 'the value of a is ' >>> print "the value of a is %03d" % a the value of a is 003 >>> print "the value of a is %+03d" % a the value of a is +03 >>> print "the name of dad is %(dad)s" % { "dad" : "jay", "mom":"cindy" } the name of dad is jay >>> print "the name of mom is %(mom)10s" % { "dad" : "jay", "mom":"cindy" } the name of mom is cindy >>> print "the name of mom is %(mom)-10s!" % { "dad" : "jay", "mom":"cindy" } the name of mom is cindy ! more info:

65 Lists lists are constructed with square brackets separating items by commas >>> lst[3] 'hello' >>> lst[1:3] [3, 'ab'] >>> lst = [[]] * 3 >>> lst [[], [], []] >>> lst = [] >>> not lst True >>> lst = [2, 3, "ab", "hello"] >>> lst = 2 * lst >>> lst [2, 3, 'ab', 'hello', 2, 3, 'ab', 'hello'] >>> lst = lst + ["world"] >>> 2 in lst True >>> min(lst)‏ 2 >>> max(lst)‏ 'world'

66 List slice list slice can refer to one or more multiple elements of a list creates a new list consisting of the indicated elements list slice: list[n:k] elements n through k -1 list[n:] elements n through last list[:k] elements 0 through k – 1 list[n:k:s] elements n through k -1 stepping by s list[:] all elements of list

67 List slice examples >>> lst = [0, 1, 2, 3, 4, 5]
[1, 2, 3] >>> lst[-3:-1] #-1 is last element in list, -3 is third to last [3, 4] >>> lst[-3:] [3, 4, 5] >>> lst[:-1] [0, 1, 2, 3, 4] >>> lst[:] [0, 1, 2, 3, 4, 5] >>> lst[2:4] = [2] >>> lst [0, 1, 2, 4, 5] >>> lst[2:4] = [2, 3, 3, 3, 4] [0, 1, 2, 3, 3, 3, 4, 5]

68 List methods lst.append(x) - append x to end of lst
lst.extend(L) - append list L to end of lst lst.insert(i, x) - insert x at position i lst.remove(x) - remove element with value x lst.pop() remove last element from lst lst.pop(i) remove element at position i lst.index(x) return index of element x lst.count(x) return count of x in lst lst.sort() sorts elements of lst lst.reverse() - reverses elements of lst

69 List methods examples >>> lst = []
>>> lst.append(3)‏ >>> lst [3] >>> lst.extend(["hello", 2, "ab", 10])‏ [3, 'hello', 2, 'ab', 10] >>> lst.insert(2, "world")‏ [3, 'hello', 'world', 2, 'ab', 10] >>> lst.append(2)‏ [3, 'hello', 'world', 2, 'ab', 10, 2] >>> lst.remove(2)‏ [3, 'hello', 'world', 'ab', 10, 2] >>> lst.pop(2)‏ 'world' >>> lst [3, 'hello', 'ab', 10, 2] >>> lst.index('ab')‏ 2 >>> lst.append(6)‏ [3, 'hello', 'ab', 10, 2, 6] >>> lst.sort()‏ [2, 3, 6, 10, 'ab', 'hello']

70 List method examples >>> lst.append("6abc")‏
[2, 3, 6, 10, 'ab', 'hello', '6abc'] >>> lst.sort()‏ [2, 3, 6, 10, '6abc', 'ab', 'hello'] >>> lst.append("ab")‏ >>> lst.count("ab")‏ 2 >>> lst.append(2)‏ >>> lst.count(2)‏ 3 >>> lst.sort()‏ >>> lst [2, 2, 2, 3, 6, 10, '6abc', 'ab', 'ab', 'hello'] >>> lst.reverse()‏ ['hello', 'ab', 'ab', '6abc', 10, 6, 3, 2, 2, 2] >>>

71 List functions filter(function, sequence) - returns a sequence consisting of those items from the sequence for which function(item) is true map(function, sequence) - calls function(item) for each of the sequence's items and returns a list of the return values reduce(function, sequence) - returns a single value constructed by calling function (a binary function) on the first two items of the sequence, then on the result and the next item, and so on

72 filter function example
>>> lst ['hello', 'ab', 'ab', '6abc', 10, 6, 3, 2, 2, 2] >>> def f(x): return x != 'ab' and x != 2 ... >>> filter(f, lst)‏ ['hello', '6abc', 10, 6, 3]

73 map function example >>> def g(x):
if (type(x) == type(1)): return x + 3 else: return x + "3" ... >>> g(3)‏ 6 >>> g("3")‏ '33' >>> lst ['hello', 'ab', 'ab', '6abc', 10, 6, 3, 2, 2, 2] >>> map(g, lst)‏ ['hello3', 'ab3', 'ab3', '6abc3', 13, 9, 6, 5, 5, 5]

74 reduce function example
>>> def h(x, y): if (type(x) == type(y)): return x + y elif (type(x) == type(1)): return str(x) + y else: return x + str(y)‏ ... >>> h(2, 3)‏ 5 >>> h("2", 3)‏ '23' >>> reduce(h, [2, 3, 4, "ab", "3e", 3, 7, "cde"])‏ '9ab3e37cde'

75 List comprehensions method for defining a list consisting of an expression followed by zero or more for or if clauses >>> vec1 = [2, 4, 6] >>> vec2 = [x*x for x in vec1] >>> vec2 [4, 16, 36] >>> [x*x for x in vec1 if x > 2] [16, 36] >>> [[x, x*x] for x in vec1] [[2, 4], [4, 16], [6, 36]] >>> [x*y for x in vec1 if x > 2 for y in vec2 if y > 4] [64, 144, 96, 216]

76 del function method for deleting an element or a slice from a list
>>> lst ['a', 'bc', 4, 8, 'hello'] >>> lst = ["a", 2, "bc", 4, 8, "hello"] >>> del(lst[1])‏ >>> del(lst[2:4])‏ ['a', 'bc', 'hello']

77 Tuples A tuple is a list of items enclosed in parenthesis (not brackets like lists)‏ Unlike lists, a tuple is immutable (can't be changed)‏ Can do much the same operations with tuples as with lists, but tuples are more efficient

78 Tuple examples >>> tup = ("a", "abc", "abcde") >>> tup = ()‏ >>> tup[0] >>> not tup 'a' True >>> tup[0] = "efg" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> tup[0:] ('a', 'abc', 'abcde')‏ >>> tup[:2] ('a', 'abc')‏ >>> len(tup)‏ 3

79 Xrange type xrange type is an immutable sequence commonly used for iteration xrange object always takes the same amount of space, no matter the range xrange objects support indexing, iteration and the len function Python also has a range type with the same functionality, but is less efficient

80 xrange/range examples
>>> r = xrange(0, 10)‏ >>> len(r)‏ 10 >>> 1 in r True >>> r[0] >>> r[9] 9 >>> lst = [] >>> for x in r: lst.append(x)‏ ... >>> lst [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> r xrange(10)‏ >>> r = range(0, 10)‏ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> r.append(10)‏ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> xr = xrange(0,10)‏ >>> xr.append(10)‏ Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'xrange' object has no attribute 'append'

81 Review of sequence types
sequence types: string, list, tuple, xrange/range support operations: in, not in, +, * >>> 2 not in [1, 2, 5, 9] False >>> 2 in (1, 2, 5, 9)‏ >>> [1, 2] * 3 [1, 2, 1, 2, 1, 2] >>> (1, 2) * 3 (1, 2, 1, 2, 1, 2)‏ >>> (1, 2) + (4, 6)‏ (1, 2, 4, 6)‏ >>> 'a' in 'abc' True >>> 'abc' + 'cde' 'abccde' >>> 2 in range(1, 5)‏ True >>> 'abc' * 3 'abcabcabc' >>> range(1, 5) * 3 [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] >>> range(1, 4) + range(1, 5)‏ [1, 2, 3, 1, 2, 3, 4]

82 Next: Dictionary type construction comparison

83 Dictionary type The dictionary type is Python's name for the associative array dictionary literal is a set of braces enclosing a comma-separated list of key-value pairs where key-value pairs are separated by a colon >>> fam = {"mom":"cindy", "dad":"jay", "oldest": "baron", "middle":"grayson", "youngest": "ethan"} >>> fam["mom"] 'cindy'

84 Dictionary type keys must be an immutable type: string, number, tuple
>>> dic = {1:"integer", "abc":"string", 3.7:"float", (1, 3):"tuple"} >>> dic[1] 'integer' >>> dic["abc"] 'string' >>> dic[3.7] 'float' >>> dic[(1, 3)] 'tuple'

85 Dictionary type dictionary elements can be added, modified or deleted
>>> dic["animal"] = "dog" >>> dic["plant"] = "grass" >>> dic {'plant': 'grass', 'animal': 'dog'} >>> dic["plant"] = "peony" {'plant': 'peony', 'animal': 'dog'} >>> del dic["plant"] {'animal': 'dog'}

86 A nested dictionary >>> family = {"mom":"carol", "dad":"mike"} >>> family["momkids"] = {"oldest":"marcia", "middle":"jan", "youngest":"cindy"} >>> family["dadkids"] = {"oldest":"greg", "middle":"peter", "youngest":"bobby"} >>> print family {'dad': 'mike', 'momkids': {'youngest': 'cindy', 'middle': 'jan', 'oldest': 'marcia'}, 'mom': 'carol', 'dadkids': {'youngest': 'bobby', 'middle': 'peter', 'oldest': 'greg'}} >>> family["housekeeper"] = "alice" {'dad': 'mike', 'housekeeper': 'alice', 'momkids': {'youngest': 'cindy', 'middle': 'jan', 'oldest': 'marcia'}, 'mom': 'carol', 'dadkids': {'youngest': 'bobby', 'middle': 'peter', 'oldest': 'greg'}}

87 Comparing dictionary types
two dictionaries are equal if they contain the same key/value pairs Note a floating point key is equal to an integer key of the same value >>> dic1 = {1: "one", 2: "two"} >>> dic2 = {2: "two", 1: "one"} >>> dic1 == dic2 True >>> dic1 = {1: "one", 2: "two"} >>> dic2 = {1.0: "one", 2: "two"} >>> dic2 {1.0: 'one', 2: 'two'} >>> dic1 == dic2 True >>> dic2[3] = "three" False

88 Next: More about types None type bool type mutable, immutable comparing data types

89 None Type used to indicate that no specific value can be, or has been, provided None is not reserved so can be bound to another value (don't do this!)‏ None evaluates to false when used in a Boolean context interpreter doesn't print out value of None >>> None >>> x = None >>> x >>>

90 Why None is useful >>> if (x): ... print "hi" ...
Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined >>> x = None

91 bool Type The names True and False reference True, False objects that are of type bool These names are mutable so you could make them references other objects (not recommended however!)‏ Like C, 0 is interpreted as false and non-zero is interpreted as true >>> a = -3 >>> if (a): print a ... -3

92 Mutable and Immutable Types
In Python we bind names to values, rather than assigning values to variables dereferencing is automatic – in an expression the name always refers to the value to which it is currently bound values to which names are bound can be mutable (can be changed) or immutable (can not be changed)‏ strings, tuples, numbers are immutable

93 Mutable and Immutable Types
Because tuples are immutable: Because lists are mutable: >>> tup = ("a", "b", "c")‏ >>> tup[0] 'a' >>> tup[0] = "d" Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object does not support item assignment >>> lst = ["a", "b", "c"] >>> lst[0] 'a' >>> lst[0] = "d" >>> lst ['d', 'b', 'c']

94 Mutable and Immutable Types
Because strings are immutable: Because dictionary keys must be immutable: >>> str = "abc" >>> str[0] = "d" Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object does not support item assignment >>> dict = {} >>> dict[[1, 2]] = 3 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: list objects are unhashable >>> dict[(1, 2)] = 3 >>> dict {(1, 2): 3}

95 Mutability Can have multiple names bound to the same mutable object
Change to the object via one name can be seen when referencing with other name >>> lst1 = [1, 2, 3] >>> lst2 = lst1 >>> lst2[0] = 4 >>> lst1 [4, 2, 3]

96 Comparing Data Types two non-numeric values of different types are always unequal The actual ordering of types depends upon the interpreter >>> "abc" == [1, 2] False >>> "abc" > [1, 2] True

97 Comparing Data Types Python uses numeric widening (narrower type is widened to that of the type being compared to) to compare numeric values >>> 3 == 3.0 True >>> 1 == 1 + 0j >>> 3.0 == 3 + 0j

98 Python statements simple statements compound statements: if, for, while function definitions and namespaces

99 Simple statements On a line by themselves, or with other simple statements separated by semi-colons assignment statement print statement del statement pass – no operation statement break – break out of its containing loop continue – terminate current execution of loop and continue with next return – return value from function global – identify name as part of global namespace

100 Compound statements consist of a clause that ends with a colon and a suite which is an indented section of code whose execution is dependent upon the clause Examples conditional execution: if ... elif ... else loops: for, while function definition: def exception handling: try

101 if .. elif .. else elif, else are optional
boolean expression must be followed by a colon suite indented on the next line; can be on the same line if it consists of only one statement >>> if (num1 < num2): min = num1 else: min = num2 ... >>> if (num1 < num2): min = num1 else: min = num2 >>>

102 (student)~/classes/5530/Python% more if.py
#!/usr/local/bin/python def aboveMiddleAge(age): if (age > 40): return "yes" return "no" def howToSpendLastYears(age): if (age < 65): return "Keep working" elif (age < 75): return "Do home repairs" elif (age < 85): return "Garden, of course" else: return "Time for rocking" i = input("Enter an age > ")‏ print "Is the age above middle age? ", aboveMiddleAge(i)‏ if (aboveMiddleAge(i) == "yes"): print "What should you do now? ", howToSpendLastYears(i)‏

103 for loop iterates over a sequence; don't modify the sequence inside the loop suite >>> family = ["jay", "cindy", "baron", "grayson", "ethan"] # list >>> for member in family: print member ... jay cindy baron grayson ethan >>>

104 >>> for l in "cat": #iterate over characters in a string
print l ... c a t >>> for animal in ("dog", "cat", "mouse"): #iterate over a tuple print animal ... dog cat mouse >>> n = 5 >>> result = 1 >>> for i in range(2, n+1): result = result * i ... >>> print result 120

105 for in dictionary >>> for member in {"dad":"jay", "mom":"cindy", "oldest":"baron", "middle":"grayson", "youngest":"ethan"}: #iterate over a dictionary print member ... dad middle oldest youngest mom >>># items returns a list of key, value tuples >>> for k, v in {'gallahad': 'the pure', 'robin': 'the brave'}.items(): print k, v ... gallahad the pure robin the brave

106 while loop suite executed repeatedly until a condition is no longer true Note for and while are python's only looping mechanisms!

107 #!/usr/local/bin/python
#print multiplication table def multTable(width, height): i = 1 j = 1 line = " " for k in range(1,width+1): line = line + ("%4d" % k)‏ print line line = "----" for k in range(1,width+1): line = line + "----" while (i <= height): print "%3d|" % i, while (j <= width): print "%3d" % (i * j), j = j + 1 i = i + 1 print "\n", multTable(9, 9)‏

108 #!/usr/local/bin/python
#count the number of time Python appears in the file words count = 0; f = open("words", "r"); while 1: line = f.read(); if (line == ""): break; #end of file print line words = line.split(); for w in words: if (w == "Python"): count = count + 1 print "The word 'Python' appeared ", count, " times"

109 Defining functions def compound statement is used to define functions
def must be followed by: name of function parenthesized list of arguments colon indented body of function (suite)‏ optional return statement terminates execution of the function; if no return or if return not given a value then the special value None is returned

110 def statement is executed
execution causes the Python interpreter to bind function name to the definition thus, binding is dynamic (occurs at runtime)‏ and, the function name binding can be changed! #!/usr/local/bin/python def f(): print "f called" def g(): print "g called" f()‏ f = g What is the output?

111 function calls create namespaces
namespace is (usually implemented as) a dictionary in which the keys are names of variables and the values are the values of those variables function namespace consists of the function arguments and local variables interpreter looks for the value of a variable in this order: local namespace – current function or method global namespace – namespace of current module built-in namespace – built-in functions and objects

112 namespace example #!/usr/local/bin/python def f(n): x = n
print "x in f:", x print "y in f:", y x = 3 y = 4 f(5)‏ print "x outside of f:", x print "y outside of f:", y Output: (student)% namespace.py x in f: 5 y in f: 4 x outside of f: 3 y outside of f: 4 Definition of x in f hides the global x

113 namespace example What happens if we access x before defining it?
#!/usr/local/bin/python def f(n): print "x in f (1):", x x = n print "x in f (2):", x print "y in f:", y x = 3 y = 4 f(5)‏ print "x outside of f:", x print "y outside of f:", y (student)~/classes/5530/Python% ./namespace2.py x in f (1): Traceback (most recent call last): File "./namespace2.py", line 11, in ? f(5)‏ File "./namespace2.py", line 4, in f print "x in f (1):", x UnboundLocalError: local variable 'x' referenced before assignment

114 global statement Python's only declaration
tells interpreter that a variable referenced within a function refers to the variable with that name in the global namespace

115 global statement example
#!/usr/local/bin/python def f(n): global x print "x in f (1):", x x = n print "x in f (2):", x print "y in f:", y x = 3 y = 4 f(5)‏ print "x outside of f:", x print "y outside of f:", y Output (student)% namespace3.py x in f (1): 3 x in f (2): 5 y in f: 4 x outside of f: 5 y outside of f: 4

116 function arguments Can pass arguments the typical way where the first formal argument initialized to the first actual, second formal to second actual, etc. Or, can provide the name of the formal argument in the call and pass them in any order (called “providing arguments by keyword”)‏ default argument values can be provided

117 function arguments #!/usr/local/bin/python def foo(a, b = 2, c = 3):
print "a = ", a, "b = ", b, "c = ", c foo(1, 2, 3)‏ foo(b = 2, c = 3, a = 1)‏ foo(1, c = 3, b = 2)‏ foo(1)‏ foo(1, b=2)‏ #This doesn't work; must provide value of a first #foo(b=2)‏ #This doesn't work, keyword arguments must come last #foo(b=2, 3, 1)‏

118 Arbitrary length argument list
last formal argument is preceded by a * to indicate the formal argument is set to a tuple of all remaining actual arguments #!/usr/local/bin/python def buildList(first, *rest): lst = [] lst.append(first)‏ for ele in rest: lst.append(ele)‏ return lst lst = buildList(1)‏ print lst lst = buildList(1, 2, 3, 4, 5)‏

119 File functions and methods
open(file [, mode]) – takes as input a string representing the file name and a mode (“r”, “w”, “a”) and returns a file object f.read([size]) – returns the next size (default is remainder of file) bytes from the file f.readline([size]) – returns the next size (default is to end of line including line terminator) bytes from file f.readlines([sizehint]) – returns a list of lines from the file (default is remainder of file); sizehint is the approximate size in bytes

120 File functions and methods
f.write(st) – writes the string str to the file; does not append line terminator f.writelines(list) – writes each member of the list to the file without appending line terminators f.close() - close the file

121 #!/usr/local/bin/python
file = open("twain.story", "r")‏ while 1: line = file.read()‏ if (line == ""): break #EOF? words = line.split() #split on whitespace dict = {} for word in words: if (word in dict): #is word a key in the dictionary? dict[word] = dict[word] + 1 else: dict[word] = 1 #print out each word and its count for word, count in dict.items(): print word, ":", count

122 Next: Modules in Python
importing modules namespaces testing modules

123 Modules in Python a module is a file of Python code
Python libraries are distributed as modules application programmers can break their code into reusable modules modules are included via a Python import statement code in file is executed via the import statement a module that is imported multiple times is still only executed once

124 Modules in Python modules are namespaces – definition of a function within a module causes its name to be stored in the module's namespace in general (although we can get around this as you'll see later), access to the functions in a module and the data defined within the module (outside a function) is via the dot operator module.foo()‏ module.num = 3

125 Modules (student)% more module1.py OUTPUT #!/usr/local/bin/python
print "module 1" (student)% more useModule1.py print "importing module1" import module1 print "importing module1 again" OUTPUT (student)% useModule1.py importing module1 module 1 importing module1 again

126 Modules (student)% more module2.py #!/usr/local/bin/python def foo():
print "foo in module2 called" print "module2: The value of str is", str str = "module2" (student)% more useModule2.py import module2 print "foo called" str = "useModule2" foo()‏ module2.foo()‏ print "useModule2: The value of str is", str print "useModule2: The value of str in module2 is", module2.str OUTPUT (student)% useModule2.py foo called foo in module2 called module2: The value of str is module2 useModule2: The value of str is useModule2 useModule2: The value of str in module2 is module2

127 Modules OUTPUT (student)% more module2.py #!/usr/local/bin/python
def foo(): print "foo in module2 called" print "module2: The value of str is", str str = "module2" OUTPUT (student) ./useModule2b.py Traceback (most recent call last): File "./useModule2b.py", line 4, in ? foo()‏ NameError: name 'foo' is not defined (student)% more useModule2b.py #!/usr/local/bin/python import module2 #trying to call foo in module2 without the dot operator foo()‏

128 Python's execution environment
sys and _builtin_ modules initialized for execution before code is read from source sys provides access to system services _builtin_ provides access to built in functions _main_ namespace created to hold names of top-level code if namespace isn't specified, a name is resolved by looking in the local namespace which is created dynamically when a function is called looking in the global namespace which is the namespace of the module currently being executed looking in the _builtin_ namespace

129 Namespaces global namespace module2 namespace module2 foo code foo
_main_ str “module2” _main_ namespace foo foo code str “useModule2”

130 Changing the module name
if a module's name is very long to type or if the name conflicts with something in your source, you can import a module and give it a different name import module as newname newname.foo() #call foo in file module.py

131 Selective imports You can specify exactly what you want to import from a module and then you can access it without the dot operator (student)% more module3.py #!/usr/local/bin/python def foo(): print "foo in module3 called" str = "module3" (student)% more useModule3.py from module3 import str, foo foo()‏ print "The value of str is", str OUTPUT (student)% useModule3.py foo in module3 called The value of str is module3

132 Module location can append a path to the path name in the sys module if your modules aren't in the directory with your “main” (student)% more library/module4.py #!/usr/local/bin/python def foo(): print "foo in module4 called" str = "module4" (student)% more useModule4.py import sys #import the python sys module sys.path.append("/u/csd/can/classes/5530/Python/library")‏ import module4 module4.foo()‏ print "The value of str is", module4.str

133 Reloading a module only the first import of a module causes it to be executed a module can be executed a second time by calling the built-in reload function (student)% more module5.py #!/usr/local/bin/python print "module 5" (student)% more useModule5.py print "importing module5" import module5 print "importing module5 again" print "reload of module5" reload(module5)‏ OUTPUT (student)% useModule5.py importing module5 module 5 importing module5 again reload of module5

134 Testing modules For you Java programmers
remember that it is convenient to put a main method in each class that is used simply to test the functionality of the methods in the class In Python, you can also place code in a module that is only executed if the name of the module's namespace is _main_ the module's namespace is _main_ only if execution begins with that module

135 Testing modules (student)~/classes/5530/Python% more math.py
#!/usr/local/bin/python #This is my math module def factorial(num): result = 1 for i in xrange(2, num+1): result = result * i return result if __name__ == '__main__': # Tests of my math module go here # These only executed if execution # begins with this module print "factorial", 5, "is", factorial(5)‏

136 Next: exception handling
try finally raising exceptions built-in exceptions

137 Exception Handling Language provided exception handling mechanisms allows programmer to focus on the normal cases, not the error handling – making the program logic simpler Python exception handling very similar to Java's two statements try...except...else try...finally

138 try ... except ... else statement
#some actions except ExceptionType1[, .. ExceptionTypeN]: #actions to take on these exceptions [except ExceptionTypeN+1[, ...ExceptionTypeM]: #actions to take on these exceptions] . [except: #actions to take on any exceptions not above] [else: #actions to take if no exception occurred]

139 try ... finally statement try: #code that allocates some resources
#code that uses the resources #if exception occurs go immediately to finally # suite finally: #finally executed whether exception occurred # or not #release the resources #if an exception occurred then it is re-raised

140 #!/usr/local/bin/python
try: num1 = input("Enter a numerator: ")‏ num2 = input("Enter a denominator: ")‏ num1 = float(num1)‏ num2 = float(num2)‏ quotient = num1/num2 except NameError: print "Must enter numeric values." except ZeroDivisionError: print "The denominator can not be zero." else: print "The value of the fraction is", quotient finally: print "Goodbye."

141 #!/usr/local/bin/python
try: num1 = input("Enter a numerator: ")‏ num2 = input("Enter a denominator: ")‏ num1 = float(num1)‏ num2 = float(num2)‏ quotient = num1/num2 finally: print "Computing..." except NameError: print "You must enter a number" except ZeroDivisionError: print "The denominator can not be zero" else: print "The value of the fraction is", quotient

142 #!/usr/local/bin/python
def getInput(): num = input("Enter a number: ")‏ return float(num)‏ def compute(num1, num2): quotient = num1/num2; return quotient try: num1 = getInput()‏ num2 = getInput()‏ quotient = compute(num1, num2)‏ except NameError: print "Must enter numeric values." except ZeroDivisionError: print "The denominator can not be zero." else: print "The value of the fraction is", quotient

143 #!/usr/local/bin/python
def getInput(): try: num = input("Enter a number: ")‏ except NameError: print "The value must be numeric." #throw Exception to main raise Exception else: return float(num)‏ def compute(num1, num2): quotient = num1/num2 except ZeroDivisionError: print "The denominator can not be zero." return quotient #my main try: num1 = getInput()‏ num2 = getInput()‏ quotient = compute(num1, num2)‏ except: print "Please try again with correct input values." else: print "The value of the fraction is", quotient

144 Raising exceptions As seen on last slide, you can use a raise statement to raise a built-in exception or a user-defined exception (more on this later)‏ The raise statement does not need to appear within a try or except suite The raise statement on its own (without an exception type) re-raises the last exception that occurred

145 Notes on exception handling
try ... finally typically nested within a try ... except ... else to allow the finally to deallocate resources and the outer except suite to handle the exception (remember the finally automatically re-raises the exception)‏ do not put too much code in the try suite, especially if multiple statements within the suite can cause the same exception exception handling is time-consuming; use it for the exceptional case, not the normal case

146 Built-in exceptions AssertionError – assert statement has failed
AttributeError – qualified name not found in the namespace of the qualified object EOFError – termination of console input FloatingPointError – fp arithmetic error IOError -I/O operation failed ImportError – problem with import statement IndexError – sequence subscript out of range KeyError – dictionary key not found KeyboardInterrupt – user has hit interrupt key

147 Built-in exceptions MemoryError – Python has run out of memory
NameError – unqualified local or global name not found NotImplementedError – usually raised by user code to indicate missing functionality OSError – OS call failed OverflowError – arithmetic result to large RuntimeError – catchall exception SyntaxError – incorrect syntax in code executed by eval or exec

148 Built-in exceptions SystemError – internal interpreter error
SystemExit – raised upon sys.exit()‏ TypeError – operation on data of wrong type UnboundLocalError – name in function referenced before value bound to it UnicodeError – encoding/decoding problem with Unicode string ValueError – operation/function applied to data with inappropriate value WindowsError – Windows-specific error ZeroDivisionError – divide by zero

149 Next: user defined classes
review of namespaces scope class definition instantiation

150 Review of namespaces namespace is a mapping of names to objects examples built-in namespace (built-in functions and exceptions)‏ created when the interpreter is started and never deleted (actually these are part of the __builtin__ module)‏ namespace of a module created when module definition is read in (for example, via an import); never deleted statements executed by the top-level invocation of the interpreter are part of the module __main__ namespace of a function created when function is executed; deleted when function exited

151 Scope textual region of a program where a namespace is accessible
scopes are determined statically (can look at the code and determine the scope) and used dynamically at least three nested scopes local namespace which is searched first global namespace which is searched second built-in namespace which is searched last

152 abs definition found in __main__ namespace
#!/usr/local/bin/python #This definition hides the abs in the built-in namespace def abs(n): print "abs in __main__ namespace" if (n < 0): return n * -1 else: return n #search for the definition of abs in the __main__ namespace absVal = abs(-3)‏ print "abs(-3)", absVal

153 invoking abs in absModule namespace
(cs)% more absModule.py def abs(n): print "abs in absModule" if (n < 0): return n * -1 else: return n (cs)% more scope2.py #!/usr/local/bin/python import absModule return absModule.abs(n) #force execution of abs in absModule absVal = abs(-3) #current namespace is __main__ print "abs(-3)", absVal

154 Class definitions class definitions (like function definitions) are executed by the interpreter causing the creation of a class object when a class definition is entered, a namespace is created; any local variables that are defined are a part of this namespace the class object that is created can be used to access the local variables in the namespace defined by the class definition

155 Classes are like functions and modules
Like functions, class statements are local scopes where names created by nested assignments live Like names in a module, names assigned in a class statement become attributes in a class object Unlike modules, attributes that are not found in a class or instance object are fetched from ancestor classes

156 Example class definition
#!/usr/local/bin/python #Class definition is executed creating a namespace class MyClass: mylocal = "mylocal within MyClass" #After execution of the class definition, the MyClass name is bound to #the class object that is created and the original scope is reinstated #The class object can be used to access the MyClass namespace print MyClass.mylocal

157 Class object class objects support two operations: attribute reference and instantiation valid attribute names are the names that were in the namespace when the class object was created instantiation is performed by using the class name as if it is a function

158 #!/usr/local/bin/python
class MyClass: mylocal = "mylocal within MyClass" def foo(self): print MyClass.mylocal print "in foo" #Data attribute reference print "data attribute reference", MyClass.mylocal #Function attribute reference #This returns a reference to a function object mymethod = MyClass.foo #instantiation of a MyClass object myinstance = MyClass()‏ #This is how the foo method would normally be called myinstance.foo()‏ #since mymethod references the foo method, I can also call it like this mymethod(myinstance)‏

159 Instance objects instance objects are created by using the class name like it is a function call object = Classname()‏ creation causes the __init__ method of Classname to be executed if one exists instance objects can only be used for attribute references; two types of attribute references references to data attributes (aka data members, instance variables)‏ references to method attributes (aka instance methods)‏

160 __init__ method automatically called
#!/usr/local/bin/python class Cat: #notice the first parameter to __init__ (and all methods)‏ #is a reference to an instance object def __init__(self, type): self.type = type def printCat(self): print "The type of this cat is", self.type cat = Cat("manx")‏ cat.printCat()‏

161 Data attributes are not declared
spring into existence when they are first assigned to (dynamically bound)‏ data attributes can be explicitly deleted with the function call: delattr(obj, attribute)‏ or the equivalent: del obj.attribute or we can delay the deletion of attributes and simply wait for them to be garbage collected

162 Method attributes method is a function that belongs to an object
all attributes of a class that are function objects define corresponding methods of its instances class Foo: #hoo is an attribute of both the class object Foo #and any instances of Foo def hoo(self, n, m): . method must be passed the object instance either explicitly or implicitly

163 #!/usr/local/bin/python
class Car: def __init__(self, type, color, doors): self.type = type self.color = color self.doors = doors def repaint(self, color): def printCar(self, header): print "%s: %s, %d doors, %s" %(header, self.color, self.doors, self.type)‏ mycar = Car("convertible", "yellow", 2)‏ #implicitly pass mycar object mycar.repaint("red")‏ #explicitly pass mycar object Car.printCar(mycar, "My car")‏ first parameter to instance method is reference to the instance object; typically this is called self, but you can name it whatever you like

164 data and method attributes can be added dynamically
#!/usr/local/bin/python class Cat: pass def printCat(self): print "The type of this cat is", self.type cat = Cat()‏ #add the data attribute to the instance object cat.type = "manx" #add the method attribute to the class object Cat.printCat = printCat cat.printCat()‏

165 Class variables and methods
Java: Class variables are shared among all instances of a class class methods can be invoked without an object can create class variables and methods simply by declaring them to be static Python a variable that is part of a class object's namespace is essentially a class variable (like myLocal) on previous slide However, if we invoke a method declared within a class without an object, we get an error

166 #!/usr/local/bin/python
class Dog: dogCount = 0; def __init__(self, type): Dog.dogCount = Dog.dogCount + 1 self.type = type def printDog(self): print "The type of this dog is", self.type def printDogCount(): print "There are", Dog.dogCount, "dogs" poodle = Dog("poodle")‏ poodle.printDog()‏ boxer = Dog("boxer")‏ boxer.printDog()‏ Dog.printDogCount()‏ OUTPUT: (student)% ./dogClass1.py The type of this dog is poodle The type of this dog is boxer Traceback (most recent call last): File "./dogClass1.py", line 21, in ? Dog.printDogCount()‏ TypeError: unbound method printDogCount() must be called with Dog instance as first argument (got nothing instead)‏

167 Python “class” methods
Python version 2.4 and later provide a staticmethod decorator which can appear on the line above a function definition to indicate the function will be a static method static methods don't have an implicit first instance argument like instance methods do Python calls these static methods, not class methods – a class method in Python is entirely different (it takes an implicit class object as its first argument)‏

168 #!/usr/local/bin/python
class Dog: dogCount = 0; def __init__(self, type): Dog.dogCount = Dog.dogCount + 1 self.type = type def printDog(self): print "The type of this dog is", self.type @staticmethod def printDogCount(): print "There are", Dog.dogCount, "dogs" poodle = Dog("poodle")‏ poodle.printDog()‏ boxer = Dog("boxer")‏ boxer.printDog()‏ #can also call printDogCount using a Dog instance Dog.printDogCount()‏ printDogCount is static method

169 Python class method foo is a class AClass: class method @classmethod
def foo(cls, msg): print "foo:", cls, msg AClass.foo("called foo with class object")‏ instance = AClass()‏ instance.foo("called foo with instance object")‏ Note that the first argument is a Class object no matter how foo is called OUTPUT (student)% classMethod.py foo: __main__.AClass called foo with class object foo: __main__.AClass called foo with instance object

170 Python class method can actually use a class method instead of a static method in the dog example that I had earlier since dogCount is an attribute of the class object, not an instance object (see next slide)‏ having access to the class object could be useful in some situations – I'm still investigating this..

171 #!/usr/local/bin/python
class Dog: dogCount = 0; def __init__(self, type): Dog.dogCount = Dog.dogCount + 1 self.type = type def printDog(self): print "The type of this dog is", self.type @classmethod def printDogCount(cls): print "There are", Dog.dogCount, "dogs" poodle = Dog("poodle")‏ poodle.printDog()‏ boxer = Dog("boxer")‏ boxer.printDog()‏ #can also call printDogCount with a Dog instance Dog.printDogCount()‏ printDogCount is class method

172 Relationship between modules and classes
Like everything else, class names always live within a module class statements are run during imports to define names, and these names become distinct module attributes since classes are attributes of modules, the dot operator must be used to reference the class unless it is an attributed of the __main__ module

173 (cs)% more person.py #!/usr/local/bin/python class Person: def __init__(self, name): self.name = name def getName(self): return self.name (cs)% more usePerson.py import person cindy = person.Person("Cindy")‏ print "My name is", cindy.getName()‏ need to give the name of the module to access the class

174 Python classes There are two types of classes in Python
classic classes Python version 2.1 and earlier only provided classic classes if x is an instance of an old-style class, then x.__class__ designates the class of x, but type(x) is always <type 'instance'> (see next slide)‏ new style classes introduced in version 2.2 to unify classes and types If x is an instance of a new-style class, then type(x) is the same as x.__class__ (see next slide + 1)‏

175 Classic class #!/usr/local/bin/python class Classic: pass
classic = Classic()‏ print "class: ", classic.__class__ print "type: ", type(classic)‏ OUTPUT (cs)% classClassic.py class: __main__.Classic type: <type 'instance'>

176 New Style class OUTPUT #!/usr/local/bin/python (cs)% classNewStyle.py
class: <class '__main__.NewStyle'> type: <class '__main__.NewStyle'> #!/usr/local/bin/python #object is parent of NewStyle class NewStyle(object): pass newstyle = NewStyle()‏ print "class: ", newstyle.__class__ print "type: ", type(newstyle)‏

177 New Style classes new style class is a class that inherits from a built-in type (or highest level type known as object) or has an ancestor class that inherits from a built-in type before new style classes, Python programmers couldn't inherit from built-in types; also a class must be new style in order to: define instance slots define properties overload the __getattribute__ method

178 Instance slots __slots__ is a class attribute that references a list of legal attributes that instances of the class can have instance attributes still must be assigned before they are referenced an of an attribute to an instance that is not listed in __slots__ results in an error note: __slots__ only works for new style classes (you can define __slots__ for classic classes, but won't get the error)

179 #!/usr/local/bin/python
class Animal(object): __slots__ = ['type', 'hasfur', 'haslegs'] def __init__(self, type, hasfur, haslegs): self.type = type self.hasfur = hasfur self.haslegs = haslegs dog = Animal("dog", "yes", "yes") dog.age = 4 assigning an age attribute to an Animal instance results in an error (cs)% slots.py Traceback (most recent call last): File "./slots.py", line 11, in <module> dog.age = 4 AttributeError: 'Animal' object has no attribute 'age'

180 Defining properties properties are provided via an object assigned to class attribute names generated by calling a property built-in with three methods (handlers for get, set, and delete operations) and a docstring accesses to the class attribute are then routed automatically to one of the accessor methods

181 #call whatcolor for reads of instance.color
#!/usr/local/bin/python class Car(object): def __init__(self, type, color): self.__type = type self.__color = color def repaint(self, color): if (color == "pink"): self.__color = "red" else: def whatcolor(self): return self.__color def settype(self, type): # can't change the type of the car pass def gettype(self): return self.__type #call whatcolor for reads of instance.color #call repaint for writes to instance.color #don't call another function on del mystance.color #no __doc__ attribute attached to color color = property(whatcolor, repaint, None, None) type = property(gettype, settype, None, None) mycar = Car("convertible", "yellow") mycar.color = "green" print "The color of my car is: ", mycar.color mycar.color = "pink" mycar.type = "minivan" print "The type of my car is: ", mycar.type notice the attribute reference is mycar.color but the instance attribute is mycar.__color (otherwise, infinite loop occurs)

182 Inheritance instance inherits attributes (data and methods) from its class class inherits attributes from all classes above it in the inheritance tree superclasses provide behavior shared by all subclasses subclasses may override behavior defined in superclasses by redefining super class names lower in the tree inheritance in python (in classic classes) is implemented simply as an attribute search from bottom to top, left to right of the inheritance tree (python supports multiple inheritance)

183 GrandPa GrandMa #!/usr/local/bin/python class GrandPa: str = "grandpa" class GrandMa: str = "grandma" class Dad(GrandPa, GrandMa): str = "dad" class Me(Dad): def getStr(self): return Me.str me = Me()‏ print "Who?", me.getStr()‏ Dad Me OUTPUT (cs)% inherit1.py Who? dad me

184 #!/usr/local/bin/python
class GrandPa: str = "grandpa" class GrandMa: str = "grandma" class Dad(GrandPa, GrandMa): pass class Me(Dad): def getStr(self): return Me.str me = Me()‏ print "Who?", me.getStr()‏ OUTPUT (cs)% inherit2.py Who? grandpa

185 #!/usr/local/bin/python
class GrandPa: str = "grandpa" class GrandMa: str = "grandma" class Dad(GrandMa, GrandPa): pass class Me(Dad): def getStr(self): return Me.str me = Me()‏ print "Who?", me.getStr()‏ OUTPUT (cs)% inherit3.py Who? grandma

186 #!/usr/local/bin/python
class GrandPa: def getStr(self): return "grandpa" class GrandMa: return "grandma" class Dad(GrandPa, GrandMa): return "Dad" class Me(Dad): return "Me" me = Me()‏ print "Who?", me.getStr()‏ OUTPUT Who? Me

187 #!/usr/local/bin/python
class GrandPa: def getStr(self): return "grandpa" class GrandMa: return "grandma" class Dad(GrandPa, GrandMa): return "Dad" class Me(Dad): pass me = Me()‏ print "Who?", me.getStr()‏ OUTPUT Who? Dad

188 #!/usr/local/bin/python
class GrandPa: def getStr(self): return "grandpa" class GrandMa: return "grandma" class Dad(GrandPa, GrandMa): pass class Me(Dad): me = Me()‏ print "Who?", me.getStr()‏ OUTPUT Who? grandpa

189 #!/usr/local/bin/python
class GrandPa: def getStr(self): return "grandpa" class GrandMa: return "grandma" class Dad(GrandMa, GrandPa): pass class Me(Dad): me = Me()‏ print "Who?", me.getStr()‏ OUTPUT Who? grandma

190 Classic versus New Style classes again
search for attributes in classic classes is depth-first python climbs all the way to the top, hugging the left side of the tree before backing up and looking to the right search for attributes in new style class is breadth-first

191 New Style Classes Classic Classes #!/usr/local/bin/python class A:
attr = "A" class B(A): pass class C(A): attr = "C" class Z(B, C): #look for attr in order: Z, B, A, C #output: A print Z().attr New Style Classes #!/usr/local/bin/python class A(object): attr = "A" class B(A): pass class C(A): attr = "C" class Z(B, C): #look for attr in order: Z, B, C, A #output: "C" print Z().attr

192 Inheritance in Python we have instance objects and class objects
the object to which an attribute is attached determines that attributes scope (where it can be located)‏ attributes attached to instances pertain only to those instances attributes attached to class objects are shared by all of their subclasses and instances

193 #!/usr/local/bin/python class Dad: def __init__(self, name="dad"):
print "Dad __init__ called" self.name = name class Me(Dad): def getname(self): return self.name class You(Dad): def __init__(self): pass #call Dad __init__ me = Me()‏ print "Who?", me.getname()‏ #call You __init__ only you = You()‏ print "Who?", you.getname()‏ OUTPUT Dad __init__ called Who? dad Who? Traceback (most recent call last): File "./inheritFoo5.py", line 27, in <module> print "Who?", you.getname()‏ File "./inheritFoo5.py", line 17, in getname return self.name AttributeError: You instance has no attribute 'name'

194 calling __init__ in superclass
#!/usr/local/bin/python class Dad: def __init__(self, name="dad"): print "Dad __init__ called" self.name = name class Me(Dad): def __init__(self, name=None): if (not name): Dad.__init__(self)‏ else: def getname(self): return self.name me = Me()‏ print "Who?", me.getname()‏ metoo = Me("Cindy")‏ print "Who?", metoo.getname()‏ OUTPUT Dad __init__ called Who? dad Who? Cindy

195 Key ideas of attribute inheritance
Superclasses are listed in parentheses in a class header Classes inherit attributes from their superclasses Instances inherit attributes from all accessible classes. When looking for a name, Python checks the instance, then its class, then all superclasses Each object.attribute reference invokes a new, independent search

196 Implementation of class and instance objects
the attributes of a namespace object are usually implemented as dictionaries class inheritance trees are just dictionaries with links to other dictionaries the __dict__ attribute is the namespace dictionary for class based objects

197 def __init__(self, name): self.name = name def getName(self):
class Person: “I am a Person” def __init__(self, name): self.name = name def getName(self): “I return a name” return self.name class Student(Person): def __init__(self, name="Anon"): Person.__init__(self, name)‏ def setGrade(self, grade): self.grade = grade joe = Student("Joe Bob")‏ joe.setGrade('C')‏ print Person.__dict__ print Student.__dict__ print joe.__dict__ OUTPUT (reformatted for readability)‏ (cs)% Student.py {'__module__': '__main__', '__doc__': 'I am a Person', '__init__': <function __init__ at 0xb7e95144>, 'getName': <function getName at 0xb7e9517c>} {'__module__': '__main__', 'setGrade': <function setGrade at 0xb7e95064>, '__init__': <function __init__ at 0xb7e951b4>, '__doc__': None} {'grade': 'C', 'name': 'Joe Bob'}

198 Other object attributes
__class__ - link from the class instance to its class (class objects do not have a __class__ attribute)‏ print joe.__class__ output: __main__.Student __bases__ - tuple of a classes superclasses (instance objects do not have a __bases__ attribute)‏ print Student.__bases__ output: (<class __main__.Person at 0xb7e6dc2c>,)‏ __name__ - attribute of class objects containing the name of the class print Student.__name__ output: Student

199 Other object attributes
__doc__ - reference to the docstring added to classes and methods print Person.__doc__ output: I am a Person print Person.getName.__doc__ output: I return a name

200 Operator Overloading operator overloading occurs when the use of an operator causes the invocation of a method operator overloading can make a program more readable database1 = database1 + database2 instead of: database1.add(database2) Python supports operator overloading by providing specially named methods to intercept operations these methods are automatically called when an operator is used

201 #!/usr/local/bin/python
class Natural: def __init__(self, start=0): if (start < 0): self.value = 0 else: self.value = start def __add__(self, value): self.value = self.value + value if (self.value < 0): #return reference to instance object return self natural = Natural(2) print "value: ", natural.value natural = natural + 2 natural = natural + -8 OUTPUT (cs)% natural.py value: 2 value: 4 value: 0 __add__ is a specially named method that is called when the + operator is used on a Natural instance

202 #!/usr/local/bin/python
class Wrapper: def __getattr__(self, attribute): if attribute in self.__dict__.keys(): return self.attribute else: return 0 class MyClass(Wrapper): pass myobject = MyClass() myobject.x = 3 print myobject.x, myobject.y I can define a Wrapper class to catch references to undefined attributes Python types call a class like Wrapper a mix-in because it can be inherited by any number of class to provide useful behavior

203 Commonly operator overloading methods
_ _init_ _ Constructor; Object creation: X = Class( ) _ _del_ _ Destructor; Object reclamation _ _add_ _ Operator +; X + Y, X += Y _ _or_ _ Operator | (bitwise OR); X | Y, X |= Y _ _repr_ _,_ _str_ _ Printing, conversions; print X, repr(X), str(X) _ _call_ _ Function calls; X( ) _ _getattr_ _ Qualification; X.undefined _ _setattr_ _ Attribute assignment; X.any = value _ _getitem_ _ Indexing; X[key], for loops and other iterations if no _ _iter_ _ _ _setitem_ _ Index assignment; X[key] = value _ _len_ _ Length; len(X), truth tests _ _cmp_ _ Comparison; X == Y, X < Y _ _lt_ _ Specific comparison; X < Y (or else _ _cmp_ _) _ _eq_ _ Specific comparison; X == Y (or else _ _cmp_ _) _ _radd_ _ Right-side operator +; Noninstance + X _ _iadd_ _ In-place (augmented) addition; X += Y (or else _ _add_ _) _ _iter_ _ Iteration contexts for loops, in tests, list comprehensions, map, others

204 Is-A versus Has-A relationship
Inheritance is typically implemented to represent an “Is-A” relationship Example: Male class which inherits from a Person class This relationship can be used to capture in the parent class behavior that is common to subclasses (Example: age, sleep attributes) Composition is used to represent a Has-A relationship A contained class provides some of the components of the containing class This is also often called Aggregation

205 #!/usr/local/bin/python
import sys class Processor: def __init__(self, reader, writer): self.reader = reader self.writer = writer def process(self): while 1: data = self.reader.readline() if not data: break data = self.converter(data) self.writer.write(data) class Uppercase(Processor): def converter(self, data): return data.upper() Uppercase(open('words.txt'), sys.stdout).process() objects for reading and writing are contained within a Processor object an Uppercase object is a Processor object

206 Extending built-in types by composition
We can wrap a built-in type with a class that provides additional or different functionality by overloading operators, we can make it look like the operators that can be applied to the built-in class also apply to our wrapper class

207 class MySet: def __init__(self, value = []): self.data = [] for v in value: if not v in self.data: self.data.append(v) def intersect(self, otherset): result = [] for v in self.data: if v in otherset: result.append(v) return MySet(result) #overload some operators def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index] def __and__(self, other): return self.intersect(other) def __repr__(self): return "A Set: " + `self.data` s1 = MySet([1, 2, 3]) print len(s1) s2 = MySet([1, 3, 5]) s3 = s1 & s2 print s3 print s3[0] OUTPUT 3 A Set: [1, 3] 1

208 Extending built-in types with inheritance
Beginning with Python 2.2, all the built-in types can now be subclassed directly Type-conversion functions such as list, str, dict, tuple have become built-in type names (type conversion functions are actually calls to a constructor, hence also the name of the built-in type) instances of the subclass can be used anywhere the original built-in type can appear

209 class MySet(list): def __init__(self, value = []): list.__init__([]) for v in value: if not v in self: self.append(v) def intersect(self, otherset): result = [] for v in self: if v in otherset: result.append(v) return MySet(result) def __and__(self, otherset): return self.intersect(otherset) def __repr__(self): return 'A Set: ' + list.__repr__(self) s1 = MySet([1, 2, 3]) s2 = MySet([1, 3, 5]) print s1 print s2 print s1 & s2 OUTPUT A Set: [1, 2, 3] A Set: [1, 3, 5] A Set: [1, 3]

210 Name mangling names inside a class statement that start with two underscores, but don't end with two underscores, are automatically expanded to include the name of the class Example: __X within class Point expanded to _Point__X Because the modified name contains the name of the enclosing class, it becomes unique the name is also now “pseudoprivate” -- you can access it, but you would have to access it with mangled name

211 Why name mangling is useful
#!/usr/local/bin/python class A: def __init__(self): self.name = "A" class B: self.name = "B" class C(A, B): B.__init__(self) A.__init__(self) c = C() print c.name print c.__dict__.keys() OUTPUT (cs)% mangle.py A ['name'] C inherits from both A and B, but its instances only have a single name attribute

212 The result of name mangling
#!/usr/local/bin/python class A: def __init__(self): self.__name = "A" class B: self.__name = "B" class C(A, B): B.__init__(self) A.__init__(self) c = C() print c.__dict__.keys() OUTPUT (cs)% mangle.py ['_B__name', '_A__name'] can't reference c.name now so the name attribute is now pseudoprivate; (in fact, there is no name attribute) however, we could reference: _A__name and _B__name

213 Name mangling provides pseudoprivate methods also
class Mangle: def __privateMethod(self): print "Hello from privateMethod" def publicMethod(self): self.__privateMethod() print "Hello from publicMethod" mymangle = Mangle() mymangle.publicMethod() mymangle.__privateMethod() OUTPUT Hello from privateMethod Hello from publicMethod Traceback (most recent call last): File "mangle.py", line 12, in <module> mymangle.__privateMethod() AttributeError: Mangle instance has no attribute '__privateMethod' However, this call: mymangle._Mangle__privateMethod() would work

214 Another way to add privacy
Besides name mangling, we already looked at how properties and slots can be used to manage access to data attributes In addition, we can use __getattr__ and __setattr__ methods __getattr__ intercepts attribute accesses to attributes that do not exist can use this to intercept accesses to constants __setattr__ intercepts all attribute assignments can use this to make sure that attributes are not modified in ways they shouldn't be

215 attribute so __getattr__ gets called when it is accessed.
class Car: def __init__(self, type, color = "blue"): self.__dict__["color"] = color self.__dict__["type"] = type def __getattr__(self, attr): if (attr == 'defaultColor'): return "blue" else: raise AttributeError, attr + \ ' does not exist' def __setattr__(self, attr, value): if (attr == 'color'): self.__dict__[attr] = value elif (attr == 'type'): ' is private' mycar = Car("sedan") print "The car is a", mycar.color, \ mycar.type print "Default car color: ", \ mycar.defaultColor mycar.color = "red" #These will generate errors: mycar.type = "convertible" mycar.defaultColor = "red" defaultColor isn't an attribute so __getattr__ gets called when it is accessed. __setattr__ is called for every data attribute access via a Car instance

216 Polymorphism the meaning of a method depends on the type of the object used to invoke it some languages include overloading in the definition of polymorphism overloading – the meaning of the method is determined by the signature since there are no type declarations, this concept doesn't apply in fact, overloading doesn't even work (see next slide)

217 (cs)% more overload.py #!/usr/local/bin/python class Overload: def method(self, arg1): print "method one called" def method(self, arg1, arg2): print "method two called" over = Overload() over.method(1, 2) over.method(1) This second definition of method redefines the first. OUTPUT (cs)% overload.py method two called Traceback (most recent call last): File "./overload.py", line 15, in <module> over.method(1) TypeError: method() takes exactly 3 arguments (2 given)

218 class Instruction: pass class Add(Instruction): def execute(self): print "do the work of an add" class Sub(Instruction): print "do the work of a sub" instructions = [Add(), Sub(), Add()] for instr in instructions: instr.execute() The meaning of execute depends upon the type of object used to invoke the execute method

219 Inheritance can be used multiple ways
Superclass is delegator superclass contains method that is used to direct control to appropriate subclass action Subclass is inheritor nothing is defined in the subclass; superclass provides all behavior Superclass behavior is replaced superclass method is overridden by method in subclass Superclass is extended superclass method extended by behavior in subclass

220 Superclass as delegator
#!/usr/local/bin/python class Delegate: def delegate(self): self.action() class Provider1(Delegate): def action(self): print "Provider1 work done here" class Provider2(Delegate): print "Provider2 work done here" Provider1().delegate() Provider2().delegate()

221 Subclass is inheritor #!/usr/local/bin/python class Superclass:
def method(self): print "all of the work done here" class Inheritor(Superclass): pass Inheritor().method()

222 Superclass behavior is replaced
#!/usr/local/bin/python class Superclass: def method(self): print "none of the work done here" class Replacer(Superclass): print "I replace the behavior in the super class" Replacer().method()

223 Superclass behavior is extended
#!/usr/local/bin/python class Superclass: def method(self): print "I do some of the work" class Extender(Superclass): Superclass.method(self) print "I do the rest of the work" Extender().method()

224 Summary of classes classes create namespaces
names defined within the class (outside of functions) and functions defined within the class are part of the namespace the class is in the namespace of the module in which it is defined when the interpreter reads the definition of a class, it creates a class object whose name is the class name the namespace of the class is referenced via the name class instances are created by using the classname like a function call

225 Summary of classes attributes are found by looking up the inheritance tree (making polymorphism easy – a natural extension) instance inherits the attributes of the class the class inherits the attributes of its parent, etc. class variables (Java terminology) are those names that are defined within the class outside of any function class methods (Java terminology) are defined by using the staticmethod and classmethod decorators (or those functions)

226 Summary of classes by default, all attributes and methods are private; can't provide some privacy by properties function and slots (for new style classes) (only applies to data attributes) name mangling – can be used on methods and data __getattr__ and __setattr__ - can be used to provide some protection of data attributes There is no notion of protected like provided by Java or C++


Download ppt "Python Programming Language"

Similar presentations


Ads by Google