Chapter 23
No programming language can anticipate all data types that a programmer might eventually need, and so object-oriented languages allow you to create new data types by defining classes. We start with a simple example to highlight the new concepts.
Listing 23.1: Sum of Dice
1 # dicesum.py
2
3 from random import randint
4
5 class Die:
6 def __init__(self):
7 self.roll()
8
9 def roll(self):
10 self.value = randint(1, 6)
11
12 def __str__(self):
13 return str(self.value)
14
15 def main():
16 rolls = int(input("Enter the number of times to roll: "))
17 die1 = Die()
18 die2 = Die()
19 counts = [0] * 13
20 for i in range(rolls):
21 die1.roll()
22 die2.roll()
23 counts[die1.value + die2.value] += 1
24 for i in range(2, 13):
25 print(str(i) + ": " + str(counts[i]))
26
27 main()
As we learn to create our own data types, it will help to have a clear understanding of the terminology:
Class A class is a template that defines objects of a new data type by specifying their state and behavior. For example, a PlayingCard class might define card objects for a game program.
Object An object is a specific instance of a class, with its own particular state. A program may create as many instances of a class as it needs. For example, a card game might create 52 PlayingCard objects to represent a deck.
State Objects have attributes or characteristics that are important to track for the purposes of a particular application. The current values of those attributes constitute the object’s state. Object state is stored in fields, sometimes more specifically referred to as instance fields. A PlayingCard might have fields to store its rank and suit.
Behavior Objects will also have behaviors that need to be modeled by an application. Object behaviors are described by methods. For example, a CardDeck class might define a shuffle() method.
Methods are called mutators if they change the state of the object or accessors if they only return information about the state.
Constructor Constructors are called to create new objects. Each class will have its own constructor.
Remember that all data types in Python are object data types and so are defined by classes. What is different now is that we are writing classes to create new data types of our own.
Classes are used to help manage the complexity that comes with building larger, more realistic programs. All class definitions begin with one line:
class <ClassName>:
<body>
Class names are capitalized. In case you have been wondering, that is why we never capitalize function or variable names (except for all-caps constants). The body of a class definition contains all of its field and method definitions.
Python is unusual in that it does not use explicit field declarations. In other words, you may have to search carefully in order to find all of the fields in a class definition. Fields are defined within the class by giving a value to a variable whose name begins with “self.” (notice the dot). That is, any variable whose name begins with “self.” is a field that is stored within the object. Every object has its own separate storage location for its fields, so that objects can hold different values in each of their fields.
Methods are defined inside the body of a class in the same way as functions, using def, except that the first parameter for every method should be a variable named self. In other words, only two things distinguish an instance method from a regular function:
As you develop code for a class, you will often find it necessary for one instance method to call another instance method inside the class implementation. Python uses the same syntax for these method calls as it does for referencing an instance field: the method name must be prefaced with “self.” For example, the __init__() method of the Die class calls the roll() method on line 7 like this:
self.roll()
If you omit “self.,” Python will assume that you are calling a regular function rather than an instance method.
In Python, methods with names that start and end with two underscores (__) will be called automatically in certain situations. Every class should define an __init__() method to give appropriate initial values to its instance fields. This is called initializing the object. In other words, __init__() is called automatically whenever the constructor creates a new object.
Most classes should also define a __str__() method, which is called any time the object appears in a print() or as an argument to str(). The __str__() method should return a string that describes the object. This doesn’t necessarily mean including everything that is known about the object, but there should be enough information included to reasonably represent the object.
As mentioned above, constructors are used to create new objects. The syntax to call a constructor in Python is:
<ClassName>(<parameters>)
The constructor for a class always has the same name as the class itself. Any parameters sent to the constructor are passed on to the class’s __init__() method.
When calling a constructor, we almost always immediately store the new object in a variable; otherwise, the object would reside in memory with no way to access it.
3.141.199.122