Initializing Objects with __init__ and self
__init__ assigns an instance’s starting attributes. Python calls it after creating the instance; self refers to that instance.
An activity diagram is a picture of a workflow: the steps an operation follows. Read this one from top to bottom, following the arrows. The filled circle marks the start, each rounded box names an action, and the bullseye marks completion. Here the workflow creates an instance and then stores its starting attributes. The diagram explains order; the Python definition below supplies the executable statements.
Define the Initializer
class Book:
def __init__(self, title, author, year):
self.title = title
self.author = author
self.year = yearEach assignment stores an argument on the new book. Defining the class prints nothing.
Run the examples in this section in order.
b1 = Book("The Bhagavad Gita", "Vyasa", -400)
print(b1.title)
print(b1.year)Output
The Bhagavad Gita
-400
Dot access reads the attributes set during initialization.
Why Initialize Attributes Together?
Without an initializer, you must assign attributes manually:
class Book:
pass
b1 = Book()
b1.title = "The Bhagavad Gita"
b1.author = "Vyasa"
b1.year = -400
b2 = Book()
b2.title = "Python Crash Course"
# You may forget to set the author of b2This creates two books but leaves the second without an author. The assignments produce no visible output.
An initializer places the required assignments in one method:
class Book:
def __init__(self, title, author, year):
self.title = title
self.author = author
self.year = year
b1 = Book("The Bhagavad Gita", "Vyasa", -400)
b2 = Book("Python Crash Course", "Eric Matthes", 2016)
print(b1.title)
print(b1.author)
print(b2.title)
print(b2.author)Output
The Bhagavad Gita
Vyasa
Python Crash Course
Eric Matthes
Both books now receive all three fields. Validation still needs explicit checks; initialization alone does not prove the values are valid.
How self Is Supplied
A sequence diagram shows which participant calls another and the order of those calls. A participant is an object or part of the program taking part in the interaction. Its dashed vertical line is a lifeline: read later messages farther down the page; the spacing does not measure elapsed seconds. Here Caller means the code making Book(...). A solid arrow points toward the new Book instance, whose box first appears at that creation message. The notes show which instance is passed to __init__ as self.
Each Book(...) label abbreviates a call with a title, author and year. The dots mean that the argument details are omitted from the diagram; use the complete calls shown in the code examples. Trace the first call to b1: inside its initializer, self.title = title stores a value on b1. The second call supplies a different instance as self, so the same method stores values on b2. The caller does not type a self argument in an ordinary Book(...) call.
b1 = Book("The Bhagavad Gita", "Vyasa", -400)This ordinary class call creates a book and supplies the instance to its initializer. It prints nothing.
The following explicit call demonstrates argument binding. It reinitializes the existing b1; it does not create another object.
Book.__init__(b1, "The Bhagavad Gita", "Vyasa", -400)No visible output.
Here you explicitly pass b1 as the first argument. In an ordinary bound method call, Python supplies that argument.
Try it: add a language parameter and store it on each book. Create two books with different languages and print both values.
With objects initialized, we can distinguish their identity, their stored values and the actions they perform.