CSE 399-004: Python Programming Lecture 2: Data, Classes, and Modules January 22, 2007 http://www.seas.upenn.edu/~cse39904/
Administrative things
Teaching assistant Brian Summa (bsumma @ seas.upenn.edu) Office hours in Moore 100A (Linux lab) Thursday 6 7pm Friday 5:30 6:30pm He'll be doing a lot of the grading on homeworks Talk to Brian S. first if you have a question about grading If that doesn't work out, talk to me next Feel free to ask him questions, as well as me 3
Other announcements Homework 2 was due this morning Homework plans: Homework 3 (Othello board) out by tomorrow Homework 4 (Othello AI) out by next week Both will be due two weeks from today My office hours: Wednesday 11 noon, 4:30 6pm 4
cse39904submit You must submit all of your files every single time you use cse39904submit to turn in something You cannot submit things in bits and pieces cse39904submit -i hwx will list the files you have submitted for hwx cse39904submit -h tells you how to use it 5
Quick poll Would you rather there be a bulletin board for discussions, as in CSE 1xx, or would you rather use the email list? I'm going to insist that all discussions happen on exactly one of these things 6
The view from here
So far in this course One lecture: Crash-course introduction to Python Basic datatypes Basic control flow How to run Python programs Two homeworks, which threw you in the ocean and asked you to swim (not so kind of me to do that ) 8
The plan from here Next 3 lectures: Talk about Python itself Everyone here comes from a wide range of backgrounds That leaves 9 lectures to talk about Python itself some more Various Python libraries Somewhere in here, you'll start working on projects Not sure what exactly will happen to homeworks Lectures will continue 9
Data in Python
What is a variable? All data in Python is represented by objects Then variables must all be references to objects That is, the memory a variable takes up is merely a pointer to some other part of memory that actually has the object We usually think of the thing being pointed to as the value of the variable, not the pointer itself 11
>>> q = [2, 3] >>> p = [1, q, 4] >>> print p [1, [2, 3], 4] >>> q[0] = 42 >>> print q [42, 3] >>> print p [1, [42, 3], 4] q The integers should also be pointers, but they're immutable, so it doesn't really matter. 2 3
>>> q = [2, 3] >>> p = [1, q, 4] >>> print p [1, [2, 3], 4] >>> q[0] = 42 >>> print q [42, 3] >>> print p [1, [42, 3], 4] p 1 4 q 2 3
>>> q = [2, 3] >>> p = [1, q, 4] >>> print p [1, [2, 3], 4] >>> q[0] = 42 >>> print q [42, 3] >>> print p [1, [42, 3], 4] p 1 4 q 42 3
p >>> q = [2, 3] >>> p = (1, q, 4) >>> print p (1, [2, 3], 4) >>> q[0] = 42 >>> print q [42, 3] >>> print p (1, [42, 3], 4) >>> p[2] = 100 1 4 42 3 (... error messages...) TypeError: 'tuple' object does not support item assignment q Notice what it means for a tuple to be immutable!
Classes: The basics
Object-oriented programming (OOP) Based on the survey results, it seems safe to assume that everyone here knows what OOP is Terminology like the following should be familiar: Class Inheritance Subclass / superclass Instances / objects Methods (instance and static) Instance variables Derived class / Base class 17
Some differences from Java Everything in a class is public No overloading Use optional arguments Don't confuse this with overriding Derived classes may have multiple base classes This is known as "multiple inheritance" You should avoid this when possible No super 18
Aside: New-style versus Classic-style Basic idea: there should be no distinction between built-in types and user-defined classes I'll try to highlight some of the differences between the two styles of classes It's unlikely you'll come out today with any real appreciation of what makes them different Just be aware that Python is in the process of transitioning to the new-style classes 19
Basic structure of a class definition class Derived(Base1, Base2): "Documentation string." <statements> Defines a class Derived which inherits from base classes Base1 and Base2 Derived will be a new-style class if it inherits from a new-style class and classic-style otherwise 20
Basic structure of a class definition class Derived(Base1, Base2): "Documentation string." <statements> You can specify no base classes, in which case you get a classic-style class You can specify the base class object if you want a new-style class that inherits as little as possible 21
Constructors class Pair(): def init (self, i, j): self.fst = i self.snd = j >>> a = Pair(2, 3) >>> print a < main.pair instance at 0x67300> 22
Constructors class Pair(): def init (self, i, j): self.fst = i self.snd = j like Java, but no new needed >>> a = Pair(2, 3) >>> print a < main.pair instance at 0x67300> 22
Constructors class Pair(): def init (self, i, j): self.fst = i self.snd = j the constructor of a class is called init >>> a = Pair(2, 3) >>> print a < main.pair instance at 0x67300> 22
Constructors class Pair(): def init (self, i, j): self.fst = i self.snd = j Did you notice that init takes 3 arguments, but we constructed an instance by only giving 2? And no optional arguments either! >>> a = Pair(2, 3) >>> print a < main.pair instance at 0x67300> 22
Self The first argument of the constructor or a method in a class is usually called self It corresponds to this in Java Since Python has no variable declarations, you need an explicit means of assigning to instance variables self provides you means of doing exactly that It also lets you call methods on the current instance 23
Self (continued) class Pair(): def init (self, i, j): fst = i snd = j def get_first(): return fst The assignments here assign to two variables fst and snd which are local to init Calling get_first() would result in an error 24
Self (continued) class Pair(): def init (self, i, j): fst = i snd = j def get_first(): return fst >>> a = Pair(2, 3) >>> a.get_first() (... error messages...) TypeError: get_first() takes no arguments (1 given) 25
Self (continued) class Pair(): def init (self, i, j): fst = i snd = j def get_first(): return fst method invocation uses familiar dot notation >>> a = Pair(2, 3) >>> a.get_first() (... error messages...) TypeError: get_first() takes no arguments (1 given) 25
Self (continued) class Pair(): def init (self, i, j): fst = i snd = j def get_first(): return fst no self argument >>> a = Pair(2, 3) >>> a.get_first() (... error messages...) TypeError: get_first() takes no arguments (1 given) namely, the instance 25
Self (continued) class Pair(): def init (self, i, j): fst = i snd = j def get_first(self): return fst >>> a = Pair(2, 3) >>> a.get_first() (... error messages...) NameError: global name 'fst' is not defined 26
Self (continued) class Pair(): def init (self, i, j): fst = i snd = j def get_first(self): return fst should assign these via self should get this from self >>> a = Pair(2, 3) >>> a.get_first() (... error messages...) NameError: global name 'fst' is not defined 26
Self (continued) class Pair(): def init (self, i, j): self.fst = i self.snd = j def get_first(self): return self.fst >>> a = Pair(2, 3) >>> a.get_first() 2 >>> a.fst 2 27
Self (continued) class Pair(): def init (self, i, j): self.fst = i self.snd = j def get_first(self): return self.fst everything is public >>> a = Pair(2, 3) >>> a.get_first() 2 >>> a.fst 2 27
Basic rules of thumb Instance variables are referred to through self For example: self.foo Methods and constructors must take at least one argument, which is called self 28
Basic rules of thumb Instance variables are referred to through self For example: self.foo Methods and constructors must take at least one argument, which is called self Technically, you can call it anything you want. The convention is to call it self. Also ignoring static methods (for now). 28
instanceof instanceof(obj, cls) Return True if obj is an instance of cls Returns False otherwise Works pretty much as you might expect 29
Single inheritance Works much as it did in Java Catch #1: Super class constructor is not called automatically (call it yourself if need be) Catch #2: No super in Python Use BaseClass.foo to refer to superclass attributes If you call super class methods like this, you have to pass in self yourself! 30
Single inheritance (example) class Pair(): def init (self, i, j): self.fst = i self.snd = j def get_first(self): return self.fst class SillyPair(Pair): def get_first(self): return Pair.get_first(self) + 50 def get_second(self): return self.get_first() + self.snd >>> a = SillyPair(2, 3) >>> a.get_second() 55 >>> a.get_first() 52 31
Single inheritance (example) class Pair(): def init (self, i, j): self.fst = i self.snd = j def get_first(self): return self.fst class SillyPair(Pair): def get_first(self): return Pair.get_first(self) + 50 def get_second(self): return self.get_first() + self.snd >>> a = SillyPair(2, 3) >>> a.get_second() 55 >>> a.get_first() 52 constructor inherited, just like any other method 31
Single inheritance (example) class Pair(): def init (self, i, j): self.fst = i self.snd = j def get_first(self): return self.fst call the superclass's version class SillyPair(Pair): def get_first(self): return Pair.get_first(self) + 50 def get_second(self): return self.get_first() + self.snd >>> a = SillyPair(2, 3) >>> a.get_second() 55 >>> a.get_first() 52 31
Single inheritance (example) class Pair(): def init (self, i, j): self.fst = i self.snd = j def get_first(self): return self.fst call a method on the current instance class SillyPair(Pair): def get_first(self): return Pair.get_first(self) + 50 def get_second(self): return self.get_first() + self.snd >>> a = SillyPair(2, 3) >>> a.get_second() 55 >>> a.get_first() 52 31
Modules: The basics
What is a module? Basic problems in programming Python: Typing things into the interpreter repeatedly gets old You want to reuse code that someone else has written Modules provide a basic way of organizing code A module mod is simply a Python file mod.py, i.e., "module" is just another name for a Python file 33
Loading modules import foo will import the module foo, which should be in the file foo.py What import foo does: If foo has already been imported, do nothing Otherwise, search for the file foo.py in the search path By default, the search path includes the current working directory and the standard library directories For now, put your modules in the current directory 34
Loading modules import foo will import the module foo, which should be in the file foo.py What import foo does: If foo has already been imported, do nothing Otherwise, search for the file foo.py in the search path Parse foo.py, raise an exception if there is a syntax error Otherwise, add foo to the list of imported modules The interpreter keeps track of all imported modules 35
Loading modules import foo will import the module foo, which should be in the file foo.py What import foo does: If foo has already been imported, do nothing Otherwise, search for the file foo.py in the search path Parse foo.py, raise an exception if there is a syntax error Otherwise, add foo to the list of imported modules Execute the code in foo.py 36
"Executing" a module About that last step: what does it mean? Each loaded module has a symbol table which contains entries for every name it defines Each statement is executed, and if necessary, an entry is added to the symbol table 37
Saving some typing from mod import foo, bar, baz Lets you use foo, bar, baz without typing "mod." from mod import * Lets you use anything from mod without typing "mod." 38
Saving some typing from mod import foo, bar, baz Lets you use foo, bar, baz without typing "mod." from mod import * Lets you use anything from mod without typing "mod." a lie, but it's good enough for now 38
Saving some typing from mod import foo, bar, baz Lets you use foo, bar, baz without typing "mod." from mod import * Lets you use anything from mod without typing "mod." >>> import sys >>> sys.stdout.write("hello!\n") Hello! >>> sys.modules {'copy_reg': <module 'copy_reg' from... 38
Saving some typing from mod import foo, bar, baz Lets you use foo, bar, baz without typing "mod." from mod import * Lets you use anything from mod without typing "mod." >>> from sys import stdout >>> stdout.write("hello!\n") Hello! >>> modules (... error messages...) NameError: name 'modules' is not defined 39
Saving some typing from mod import foo, bar, baz Lets you use foo, bar, baz without typing "mod." from mod import * Lets you use anything from mod without typing "mod." >>> from sys import * >>> stdout.write("hello!\n") Hello! >>> modules {'copy_reg': <module 'copy_reg' from... 40
Saving some typing The from forms of import don't define the module name! >>> from sys import * >>> sys.stdout.write("hello!\n") Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'sys' is not defined 41
Tips about importing modules Python evaluates the contents of a module only the first time it's imported Avoid from mod import * when possible It clutters the namespace It becomes difficult to determine who defined what 42
Modules as programs Many tools for Python import modules so that they can analyze them Therefore, it is a bad idea if non-trivial code gets executed when a module is imported For example: def foo(): return 42 print "Hello!" not a good idea 43
Modules as programs If you're "running" a file bar.py as a program, then in that case, bar. name will be ' main '. bar.py def foo(): return 42 if name == " main ": print "Hello!" >>> import bar >>> bar. name 'bar' 44
Modules as programs If you're "running" a file bar.py as a program, then in that case, bar. name will be ' main '. bar.py def foo(): return 42 if name == " main ": print "Hello!" prompt$ python bar.py Hello! 45
Next time More on classes Scoping and namespaces in Python Times after that: Review some basic datatypes and constructs Exceptions Generators (?) Iterators (?) 46