lecture 17: classes - cornell university · lecture 17: classes (chapter 15) cs 1110 introduction...
TRANSCRIPT
Lecture 17: Classes
(Chapter 15)CS 1110
Introduction to Computing Using Python
[E. Andersen, A. Bracy, D. Gries, L. Lee, S. Marschner, C. Van Loan, W. White]
http://www.cs.cornell.edu/courses/cs1110/2018sp
Announcements• Lab 9 is out (just 2 of the 4 problems)• IMPORTANT: A3 updates on website!
• More recursion examples, see the demos:§ http://www.cs.cornell.edu/courses/cs1110/2014sp/lectures/index.php§ https://www.cs.cornell.edu/courses/cs1110/2016fa/lectures/10-18-
16/modules/morefun.py
• More daily practice: download the demo code we post for each lecture; remove the contents, and try to reproduce what we did in class. Or try to modify it in new ways. 2
Recall: Objects as Data in Folders
• An object is like a manila folder• Contains other variables
§ Variables are called attributes§ Can change attribute values
(w/ assignment statements)• Has a “tab” that identifies it
§ Unique number assigned by Python§ Fixed for lifetime of the object
• Has a type listed in the cornernums = [2,3,5]nums[1] = 7 3
id1
0 2 1 3 2 5
list
type
unique identifier
7
id1nums
Classes are user-defined Types
Classes are how we add new types to Python
Example Classes• Point3• Card• Rect• Person
4
id2
x 2
y 3
z 5
Point3
class name
Simple Class Definition
class <class-name>():
"""Class specification"""<function definitions>
5
class Worker():"""An instance is a worker in an organization.
Instance has basic worker info, but no salary information.
ATTRIBUTES:lname: Worker’s last name. [str]ssn: Social security no. [int in 0..999999999]boss: Worker's boss. [Worker, or None if no boss]
The Class Specification
6
Description
Invariant
Shortsummary
Moredetail
Attributelist
AttributeName
0.. 999999999 means from 0 to 999999999, inclusiveThis is handy notation, not Python.
Constructors
• Function to create new instances§ function name is the class name
§ Created for you automatically
• Calling the constructor:§ Makes a new object folder
§ Initializes attributes (see next slide)
§ Returns the id of the folder
w = Worker('Andersen', 1234, None)
id8w
7
id8
lname 'Andersen'
ssn
boss
1234
None
Worker
Special Method: __init__
def __init__(self, last_name, ssn, boss):"""Initializer: creates a Worker
Has last_name, ssn, and boss
Pre: last_name a string, ssn an int inrange 0..999999999, and boss either a Worker or None.self.lname = last_nameself.ssn = ssnself.boss = boss
w = Worker('Andersen', 1234, None) # this is the call to the constructor# the constructor calls __init__ 8
id8
lname 'Erik'
ssn
boss
1234
None
Worker
two underscores
use self to assign
attributes
ß called by the constructor
Evaluating a Constructor Expression
Worker('Erik', 1234, None)
1. Creates a new object (folder) of the class Worker on the heap§ Folder is initially empty
2. Executes the method __init__§ self = folder name = identifier§ Other arguments passed in order§ Executes commands in initializer
3. Returns folder name, the identifier
id8
lname 'Erik'
ssn
boss
1234
None
Worker
9
Invariants
• Properties of an attribute that must be true• Works like a precondition:
§ If invariant satisfied, object works properly§ If not satisfied, object is “corrupted”
• Examples:§ Point3 class: all attributes must be ints§ RGB class: all attributes must be ints in 0..255
• Purpose of the class specification10
Checking Invariants with an Assert
class Student():"""Instance is a student taking python"""def __init__(self, name, NetID, is_auditing):
"""Initializer: instance with name, NetID, auditing status
name: student's full name [str]NetID: student's NetID [str], 2-3 letters + 1-4 numbersis_auditing: whether student is auditing the class [bool]"""
self.name = nameself.NetID = NetIDself.is_auditing = is_auditing
11
assert type(name) == str, "name should be type str"assert type(NetID) == str, "NetID should be type str"assert type(is_auditing) == bool, "is_auditing should be type bool"
Class Attributes
Class Attributes: Variables that belong to the Class• One variable for the whole Class• Shared by all object instances• Access by <Class Name>.<attribute-name>
Why?• Some variables are relevant to every object instance of a class• Does not make sense to make them object attributes• Doesn’t make sense to make them global variables, either
Example: Suppose we want to keep track of how many students are enrolled in CS 1110 12
Class Variables for CS1110
class Student():"""Instance is a student taking python""”
enrollment = 0
def __init__(self, name, NetID, is_auditing):"""Initializer: instance with name, NetID, auditing status
name: student's full name [str]NetID: student's NetID [str], 2-3 letters + 1-4 numbersis_auditing: whether student is auditing the class [bool]"""self.name = nameself.NetID = NetIDself.is_auditing = is_auditingStudent.enrollment = Student.enrollment + 1
13
Where does this variable live???
Classes Have Folders Too
Object Folders
• Separate for each instance• Example: 2 Student objects
Class Folders
• Data common to all instances
• Not just data!• Everything common to all
instances goes here!
14
Studentid1id1p1 StudentJon Linamejl200NetIDTrueis_auditing
id2p2
id2Student
Jill Banamejb110NetIDFalseis_auditing
2enrollment
Recall: Objects can have MethodsFunction: call with object as argument
<function-name>(<arguments>)len(my_list)
Method: function tied to the object<object-variable>.<function-call>my_list.count(7)
• Attributes live in object folder• Class Attributes live in class folder• Methods live in class folder
15
id1Student
Jon Linamejl200NetIDTrueis_auditing
__init__(self, name, NetID, is_auditing)
Student
2enrollment
Complete Class Definition
class <class-name>():
"""Class specification"""<assignment statements>
<function definitions>
keyword classBeginning of a class definition
Specification(similar to one for a function)
to define methods
to define class variables
16
class Student():"""Specification goes here.""”enrollment = 0def __init__(self, last_name, ssn, boss):
. . . <snip> . . .
__init__(self, name, NetID, is_auditing)
Student
0enrollment
Python creates after reading the class definition
Method Definitions• Looks like a function def
§ But indented inside class§ 1st parameter always self
Example: p1.greet() § Go to class folder for p1
(i.e., Student) that’s where greet is defined
§ Now greet is called with p1 as its first argument
§ This way, greet knows whichinstance of Student it isworking with
class Student():def __init__(self, name, NetID, is_auditing):
self.name = nameself.NetID = NetIDself.is_auditing = is_auditingStudent.enrollment = Student.enrollment + 1
def greet(self):"""Prints information about theStudent to the screen"""print("Hi! My name is "+ self.name)print(”My NetID is "+ self.NetID)if self.is_auditing:
print("I'm auditing the class")17
__init__(self, …)greet(self)
Student0enrollment
Class Gotchas… and how to avoid them
Rules to live by:1. Refer to Class Variables using the Class Name
s1 = Student(“Jon Li”, “jl200”, True)print(“current enrollment = “+str(Student.enrollment))
2. Don’t forget self
18
Name Resolution for Objects
• ⟨object⟩.⟨name⟩ means § Go the folder for object
§ Find attribute/method name
§ If missing, check class folder§ If not in either, raise error
s1 = Student(“Jon Li”, “jl200”, True)# finds attribute in object folderprint(s1.name) # finds attribute in class folderprint(s1.enrollment) ß dangerous
19
id1id1s1 StudentJon Linamejl200NetIDTrueis_auditing
__init__(self, name, NetID, is_auditing)
Student
1enrollment
Accessing vs.Modifying Class Variables
• Recall: you cannot assign to a global variable from inside a function call
• Similarly: you cannot assign to a class attribute from “inside” an object variable
s1 = Student(“Jon Li”, “jl200”, True)Student.enrollment = 2 # updates class variables1.enrollment = 9 # creates new object
# variable called enrollmentBetter to refer to Class Variables using the Class Name
20
What gets Printed? (Q)
21
import cs1110
s1 = cs1110.Student(“Jon Li”, “jl200”, True)print(s1.enrollment)s2 = cs1110.Student(“Jill Bo”, “jb20”, False)print(s2.enrollment)s2.enrollment = 3print(s1.enrollment)print(s2.enrollment)print(cs1110.Student.enrollment)
C: 12232
A: 12333
B: 12332
D: 11333
What gets Printed? (A)
22
import cs1110
s1 = cs1110.Student(“Jon Li”, “jl200”, True)print(s1.enrollment)s2 = cs1110.Student(“Jill Bo”, “jb20”, False)print(s2.enrollment)s2.enrollment = 3print(s1.enrollment)print(s2.enrollment)print(cs1110.Student.enrollment)
What?!?&%$?? Look at that in the Python Tutor.
C: 12232
A: 12333
B: 12332
D: 11333
Don’t forget self, Part 1
23
s1 = Student(“Jon Li”, “jl200”, True)s1.greet()
TypeError: greet() takes 0positional arguments but 1 was given
<var>.<method_name> always passes <var> as first argument
class Student():
"""Prints information about theStudent to the screen"""def greet(self): # forgotten by you or me
print("Hi! My name is "+self.name)print(”My NetID is "+self.NetID)if self.is_auditing:
print("I'm auditing the class")
Don’t forget self, Part 2
24
s1 = Student(“Jon Li”, “jl200”, True)s1.greet()
NameError: global name ‘is_auditing' is not defined
<var>.<method_name> always passes <var> as first argument
class Student():
"""Prints information about theStudent to the screen"""def greet(self):
print("Hi! My name is "+self.name)print(”My NetID is "+self.NetID)if self.is_auditing: # forgot self!
print("I'm auditing the class")
Aside: The Value None
• The boss field is a problem.§ boss refers to a Worker object§ Some workers have no boss§ Or maybe not assigned yet
• Solution: use value None§ None: Lack of (folder) name§ Will reassign the field later!
25
id8
lname 'Erik'
ssn
boss
1234
None
Worker
Making Arguments Optional
• We can assign default values to __init__ arguments§ Write as assignments to
parameters in definition§ Parameters with default values
are optional• Examples:
§ p = Point3() # (0,0,0)§ p = Point3(1,2,3) # (1,2,3)§ p = Point3(1,2) # (1,2,0)§ p = Point3(y=3) # (0,3,0)§ p = Point3(1,z=2) # (1,0,2)
class Point3():"""Instances are points in 3d space
x: x coord [int]y: y coord [int]z: z coord [int] """
def __init__(self,x=0,y=0,z=0):"""Initializer: makes a new PointPrecondition: x,y,z are numbers"""self.x = xself.y = yself.z = z
…
26