Identity, State, and Behavior
An object has an identity, a current state and behavior. Two books may store the same title and still be different objects.
As in the earlier object diagram, underlined labels identify objects; the compartment below each label shows a stored value. No line connects them because equal titles alone do not create a relationship.
Identity
is compares identity. == uses the type’s equality rule; our Book has not defined a custom rule.
class Book:
def __init__(self, title):
self.title = title
book1 = Book("Hamlet")
book2 = Book("Hamlet")
print(book1 is book2)
print(book1 == book2)
print(book1.title == book2.title)Output
False
False
True
The books are separate objects, but their title strings are equal. id() also returns an identity number; treating it as a memory address is implementation-specific.
State
State is the data held by an object at a particular time. Here, None means no courses list was supplied. The conditional expression chooses a new empty list in that case; otherwise list(courses) copies the supplied list.
class Student:
def __init__(self, name, courses=None):
self.name = name
self.courses = [] if courses is None else list(courses)
ada = Student("Ada")
grace = Student("Grace", ["CS101"])
print(ada.name, ada.courses)
print(grace.name, grace.courses)Output
Ada []
Grace ['CS101']
Ada has an empty courses list; Grace has CS101. The initializer creates or copies a list, so their collections are independent.
Continue with the students above:
ada.courses.append("Math101")
print(ada.courses)Output
['Math101']
Appending changes Ada’s state. Grace’s courses are unchanged.
Behavior
A method can update state or return information from it.
class Student:
def __init__(self, name):
self.name = name
self.courses = []
def enroll(self, course):
self.courses.append(course)
def full_name(self):
return self.name
ada = Student("Ada Lovelace")
ada.enroll("CS101")
print(ada.full_name())
print(ada.courses)Output
Ada Lovelace
['CS101']
enroll changes the courses list. full_name returns the stored name.
Try it: create another Ada object. Compare the objects with is, then compare their names with ==.
We can now separate values stored on individual objects from defaults supplied by their class.