forked from csev/py4e
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path14-objects.php
More file actions
377 lines (346 loc) · 28.3 KB
/
14-objects.php
File metadata and controls
377 lines (346 loc) · 28.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
<?php if ( file_exists("../booktop.php") ) {
require_once "../booktop.php";
ob_start();
}?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<title></title>
<style type="text/css">code{white-space: pre;}</style>
</head>
<body>
<h1 id="object-oriented-programming">Object-Oriented Programming</h1>
<h2 id="managing-larger-programs">Managing Larger Programs</h2>
<p></p>
<p>At the beginning of this book, we came up with four basic programming patterns which we use to construct programs:</p>
<ul>
<li>Sequential code</li>
<li>Conditional code (if statements)</li>
<li>Repetitive code (loops)</li>
<li>Store and reuse (functions)</li>
</ul>
<p>In later chapters, we explored simple variables as well as collection data structures like lists, tuples, and dictionaries.</p>
<p>As we build programs, we design data structures and write code to manipulate those data structures. There are many ways to write programs and by now, you probably have written some programs that are "not so elegant" and other programs that are "more elegant". Even though your programs may be small, you are starting to see how there is a bit of "art" and "aesthetic" to writing code.</p>
<p>As programs get to be millions of lines long, it becomes increasingly important to write code that is easy to understand. If you are working on a million line program, you can never keep the entire program in your mind at the same time. So we need ways to break the program into multiple smaller pieces so to solve a problem, fix a bug, or add a new feature we have less to look at.</p>
<p>In a way, object oriented programming is a way to arrange your code so that you can zoom into 500 lines of the code, and understand it while ignoring the other 999,500 lines of code for the moment.</p>
<h2 id="getting-started">Getting Started</h2>
<p>Like many aspects of programming it is necessary to learn the concepts of object oriented programming before you can use them effectively. So approach this chapter as a way to learn some terms and concepts and work through a few simple examples to lay a foundation for future learning. Throughout the rest of the book we will be using objects in many of the programs but we won't be building our own new objects in the programs.</p>
<p>The key outcome of this chapter is to have a basic understanding of how objects are constructed and how they function and most importantly how we make use of the capabilities of objects that are provided to us by Python and Python libraries.</p>
<h2 id="using-objects">Using Objects</h2>
<p>It turns out we have been using objects all along in this class. Python provides us with many built-in objects. Here is some simple code where the first few lines should feel very simple and natural to you.</p>
<p></p>
<pre class="python"><code>stuff = list()
stuff.append('python')
stuff.append('chuck')
stuff.sort()
print (stuff[0])
print (stuff.__getitem__(0))
print (list.__getitem__(stuff,0))
# Code: http://www.py4e.com/code3/party1.py</code></pre>
<p>But instead of focusing on what these lines accomplish, lets look at what is really happening from the point of view of object-oriented programming. Don't worry if the following paragraphs don't make any sense the first time you read them because we have not yet defined all these terms.</p>
<p>The first line is <em>constructing</em> an object of type <em>list</em>, the second and third lines are calling the <code>append()</code> <em>method</em>, the fourth line is calling the <code>sort()</code> <em>method</em>, and the fifth line is retrieving the item at position 0.</p>
<p>The sixth line is calling the <code>__getitem__()</code> method in the <code>stuff</code> list with a parameter of zero.</p>
<pre class="python"><code>print (stuff.__getitem__(0))</code></pre>
<p>The seventh line is an even more verbose way of retrieving the 0th item in the list.</p>
<pre class="python"><code>print (list.__getitem__(stuff,0))</code></pre>
<p>In this code, we care calling the <code>__getitem__</code> method in the <code>list</code> class and passing in the list (<code>stuff</code>) and the item we want retrieved from the list as parameters.</p>
<p>The last three lines of the program are completely equivalent, but it is more convenient to simply use the square bracket syntax to look up an item at a particular position in a list.</p>
<p>We can take a look into the capabilities of an object by looking at the output of the <code>dir()</code> function:</p>
<pre><code>>>> stuff = list()
>>> dir(stuff)
['__add__', '__class__', '__contains__', '__delattr__',
'__delitem__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__',
'__gt__', '__hash__', '__iadd__', '__imul__', '__init__',
'__iter__', '__le__', '__len__', '__lt__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__reversed__', '__rmul__', '__setattr__',
'__setitem__', '__sizeof__', '__str__', '__subclasshook__',
'append', 'clear', 'copy', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
>>></code></pre>
<p>The precise definition of <code>dir()</code> is that it lists the <em>methods</em> and <em>attributes</em> of a Python object.</p>
<p>The rest of this chapter will define all of the above terms so make sure to come back after you finish the chapter and re-read the above paragraphs to check your understanding.</p>
<h2 id="starting-with-programs">Starting with Programs</h2>
<p>A program in its most basic form takes some input, does some processing, and produces some output. Our elevator conversion program demonstrates a very short but complete program showing all three of these steps.</p>
<pre class="python"><code>usf = input('Enter the US Floor Number: ')
wf = int(usf) - 1
print('Non-US Floor Number is',wf)
# Code: http://www.py4e.com/code3/elev.py</code></pre>
<p>If we think a bit more about this program, there is the "outside world" and the program. The input and output aspects are where the program interacts with the outside world. Within the program we have code and data to accomplish the task the program is designed to solve.</p>
<div class="figure">
<img src="../images/program.svg" alt="A Program" />
<p class="caption">A Program</p>
</div>
<p>When we are "in" the program, we have some defined interactions with the "outside" world, but those interactions are well defined and generally not something we focus on. While we are coding we worry only about the details "inside the program".</p>
<p>One way to think about object oriented programming is that we are separating our program into multiple "zones". Each "zone" contains some code and data (like a program) and has well defined interactions with the outside world and the other zones within the program.</p>
<p>If we look back at the link extraction application where we used the BeautifulSoup library, we can see a program that is constructed by connecting different objects together to accomplish a task:</p>
<p> </p>
<pre class="python"><code># To run this, you can install BeautifulSoup
# https://pypi.python.org/pypi/beautifulsoup4
# Or download the file
# http://www.py4e.com/code3/bs4.zip
# and unzip it in the same directory as this file
import urllib.request, urllib.parse, urllib.error
from bs4 import BeautifulSoup
import ssl
# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
url = input('Enter - ')
html = urllib.request.urlopen(url, context=ctx).read()
soup = BeautifulSoup(html, 'html.parser')
# Retrieve all of the anchor tags
tags = soup('a')
for tag in tags:
print(tag.get('href', None))
# Code: http://www.py4e.com/code3/urllinks.py</code></pre>
<p>We read the URL into a string, and then pass that into <code>urllib</code> to retrieve the data from the web. The <code>urllib</code> library uses the <code>socket</code> library to make the actual network connection to retrieve the data. We take the string that we get back from <code>urllib</code> and hand it to BeautifulSoup for parsing. BeautifulSoup makes use of another object called <code>html.parser</code><a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a> and returns an object. We call the <code>tags()</code> method in the returned object and then get a dictionary of tag objects, and loop through the tags and call the <code>get()</code> method for each tag to print out the 'href' attribute.</p>
<div class="figure">
<img src="../images/program-oo.svg" alt="A Program as Network of Objects" />
<p class="caption">A Program as Network of Objects</p>
</div>
<p>We can draw a picture of this program and how the objects work together.</p>
<p>The key here is not to fully understand how this program works but to see how we build a network of interacting objects and orchestrate the movement of information between the objects to create a program. It is also important to note that when you looked at that program several chapters back, you could fully understand what was going on in the program without even realizing that the program was "orchestrating the movement of data between objects". Back then it was just lines of code that got the job done.</p>
<h2 id="subdividing-a-problem---encapsulation">Subdividing a Problem - Encapsulation</h2>
<p>One of the advantages of the object oriented approach is that it can hide complexity. For example, while we need to know how to use the <code>urllib</code> and BeautifulSoup code, we do not need to know how those libraries work internally. It allows us to focus on the part of the problem we need to solve and ignore the other parts of the program.</p>
<div class="figure">
<img src="../images/program-oo-code.svg" alt="Ignoring Detail When Using an Object" />
<p class="caption">Ignoring Detail When Using an Object</p>
</div>
<p>This ability to focus on a part of a program that we care about and ignore the rest of the program is also helpful to the developers of the objects. For example the programmers developing BeautifulSoup do not need to know or care about how we retrieve our HTML page, what parts we want to read or what we plan to do with the data we extract from the web page.</p>
<div class="figure">
<img src="../images/program-oo-bs4.svg" alt="Ignoring Detail When Building an Object" />
<p class="caption">Ignoring Detail When Building an Object</p>
</div>
<p></p>
<p>Another word we use to capture this idea that we ignore the internal detail of objects we use is "encapsulation". This means that we can know how to use an object without knowing how it internally accomplishes what we need done.</p>
<h2 id="our-first-python-object">Our First Python Object</h2>
<p>At its simplest, an object is some code plus data structures that is smaller than a whole program. Defining a function allows us to store a bit of code and give it a name and then later invoke that code using the name of the function.</p>
<p>An object can contain a number of functions (which we call "methods") as well as data that is used by those functions. We call data items that are part of the object "attributes".</p>
<p></p>
<p>We use the <code>class</code> keyword to define the data and code that will make up each of the objects. The class keyword includes the name of the class and begins an indented block of code where we include the attributes (data) and methods (code).</p>
<pre class="python"><code>class PartyAnimal:
x = 0
def party(self) :
self.x = self.x + 1
print("So far",self.x)
an = PartyAnimal()
an.party()
an.party()
an.party()
PartyAnimal.party(an)
# Code: http://www.py4e.com/code3/party2.py</code></pre>
<p>Each method looks like a function, starting with the <code>def</code> keyword and consisting of an indented block of code. This example has one attribute (x) and one method (party). The methods have a special first parameter that we name by convention <code>self</code>.</p>
<p>Much like the <code>def</code> keyword does not cause function code to be executed, the <code>class</code> keyword does not create an object. Instead, the <code>class</code> keyword defines a template indicating what data and code will be contained in each object of type <code>PartyAnimal</code>. The class is like a cookie cutter and the objects created using the class are the cookies<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a>. You don't put frosting on the cookie cutter, you put frosting on the cookies - and you can put different frosting on each cookie.</p>
<div class="figure">
<img src="../photos/cookie_cutter_flickr_Didriks.png" alt="A Class and Two Objects" />
<p class="caption">A Class and Two Objects</p>
</div>
<p>If you continue through the example code, we see the first executable line of code:</p>
<pre class="python"><code>an = PartyAnimal()</code></pre>
<p> </p>
<p>This is where we instruct Python to construct (e.g. create) an <em>object</em> or "instance of the class named PartyAnimal". It looks like a function call to the class itself and Python constructs the object with the right data and methods and returns the object which is then assigned to the variable <code>an</code>. In a way this is quite similar to the following line which we have been using all along:</p>
<pre class="python"><code>counts = dict()</code></pre>
<p>Here we are instructing Python to construct an object using the <code>dict</code> template (already present in Python), return the instance of dictionary and assign it to the variable <code>counts</code>.</p>
<p>When the PartyAnimal class is used to construct an object, the variable <code>an</code> is used to point to that object. We use <code>an</code> to access the code and data for that particular instance of a PartyAnimal object.</p>
<p>Each Partyanimal object/instance contains within it a variable <code>x</code> and a method/function named <code>party</code>. We call that <code>party</code> method in this line:</p>
<pre class="python"><code>an.party()</code></pre>
<p>When the <code>party</code> method is called, the first parameter (which we call by convention <code>self</code>) points to the particular instance of the PartyAnimal object that <code>party</code> is called from within. Within the <code>party</code> method, we see the line:</p>
<pre class="python"><code>self.x = self.x + 1</code></pre>
<p>This syntax using the 'dot' operator is saying 'the x within self'. So each time <code>party()</code> is called, the internal <code>x</code> value is incremented by 1 and the value is printed out.</p>
<p>To help make sense of the difference between a global function and a method within a class/object, the following line is another way to call the <code>party</code> method within the <code>an</code> object:</p>
<pre class="python"><code>PartyAnimal.party(an)</code></pre>
<p>In this variation, we are accessing the code from within the <em>class</em> and explicitly passing the object pointer <code>an</code> in as the first parameter (i.e. <code>self</code> within the method). You can think of <code>an.party()</code> as shorthand for the above line.</p>
<p>When the program executes, it produces the following output:</p>
<pre><code>So far 1
So far 2
So far 3
So far 4</code></pre>
<p>The object is constructed, and the <code>party</code> method is called four times, both incrementing and printing the value for <code>x</code> within the <code>an</code> object.</p>
<h2 id="classes-as-types">Classes as Types</h2>
<p> </p>
<p>As we have seen, in Python, all variables have a type. And we can use the built-in <code>dir</code> function to examine the capabilities of a variable. We can use <code>type</code> and <code>dir</code> with the classes that we create.</p>
<pre class="python"><code>class PartyAnimal:
x = 0
def party(self) :
self.x = self.x + 1
print("So far",self.x)
an = PartyAnimal()
print ("Type", type(an))
print ("Dir ", dir(an))
print ("Type", type(an.x))
print ("Type", type(an.party))
# Code: http://www.py4e.com/code3/party3.py</code></pre>
<p>When this program executes, it produces the following output:</p>
<pre><code>Type <class '__main__.PartyAnimal'>
Dir ['__class__', '__delattr__', ...
'__sizeof__', '__str__', '__subclasshook__',
'__weakref__', 'party', 'x']
Type <class 'int'>
Type <class 'method'></code></pre>
<p>You can see that using the <code>class</code> keyword, we have created a new type. From the <code>dir</code> output, you can see both the <code>x</code> integer attribute and the <code>party</code> method are available in the object.</p>
<h2 id="object-lifecycle">Object Lifecycle</h2>
<p> </p>
<p>In the previous examples, we are defining a class (template) and using that class to create an instance of that class (object) and then using the instance. When the program finishes, all the variables are discarded. Usually we don't think much about the creation and destruction of variables, but often as our objects become more complex, we need to take some action within the object to set things up as the object is being constructed and possibly clean things up as the object is being discarded.</p>
<p>If we want our object to be aware of these moments of construction and destruction, we add specially named methods to our object:</p>
<pre class="python"><code>class PartyAnimal:
x = 0
def __init__(self):
print('I am constructed')
def party(self) :
self.x = self.x + 1
print('So far',self.x)
def __del__(self):
print('I am destructed', self.x)
an = PartyAnimal()
an.party()
an.party()
an = 42
print('an contains',an)
# Code: http://www.py4e.com/code3/party4.py</code></pre>
<p>When this program executes, it produces the following output:</p>
<pre><code>I am constructed
So far 1
So far 2
I am destructed 2
an contains 42</code></pre>
<p>As Python is constructing our object, it calls our <code>__init__</code> method to give us a chance to set up some default or initial values for the object. When Python encounters the line:</p>
<pre><code>an = 42</code></pre>
<p>It actually 'thows our object away' so it can reuse the <code>an</code> variable to store the value <code>42</code>. Just at the moment when our <code>an</code> object is being 'destroyed' our destructor code (<code>__del__</code>) is called. We cannot stop our variable from being destroyed, but we can do any necessary cleanup right before our object no longer exists.</p>
<p>When developing objects, it is quite common to add a constructor to an object to set in initial values in the object, it is relatively rare to need a destructor for an object.</p>
<h2 id="many-instances">Many Instances</h2>
<p>So far, we have been defining a class, making a single object, using that object, and then throwing the object away. But the real power in object oriented happens when we make many instances of our class.</p>
<p>When we are making multiple objects from our class, we might want to set up different initial values for each of the objects. We can pass data into the constructors to give each object a different initial value:</p>
<pre class="python"><code>class PartyAnimal:
x = 0
name = ''
def __init__(self, nam):
self.name = nam
print(self.name,'constructed')
def party(self) :
self.x = self.x + 1
print(self.name,'party count',self.x)
s = PartyAnimal('Sally')
j = PartyAnimal('Jim')
s.party()
j.party()
s.party()
# Code: http://www.py4e.com/code3/party5.py</code></pre>
<p>The constructor has both a <code>self</code> parameter that points to the object instance and then additional parameters that are passed into the constructor as the object is being constructed:</p>
<pre><code>s = PartyAnimal('Sally')</code></pre>
<p>Within the constructor, the line:</p>
<pre><code>self.name = nam</code></pre>
<p>Copies the parameter that is passed in (<code>nam</code>) into the <code>name</code> attribute within the object instance.</p>
<p>The output of the program shows that each of the objects (<code>s</code> and <code>j</code>) contain their own independent copies of <code>x</code> and <code>nam</code>:</p>
<pre><code>Sally constructed
Sally party count 1
Jim constructed
Jim party count 1
Sally party count 2</code></pre>
<h2 id="inheritance">Inheritance</h2>
<p>Another powerful feature of object oriented programming is the ability to create a new class by extending an existing class. When extending a class, we call the original class the 'parent class' and the new class as the 'child class'.</p>
<p>For this example, we will move our <code>PartyAnimal</code> class into its own file:</p>
<pre class="python"><code>class PartyAnimal:
x = 0
name = ''
def __init__(self, nam):
self.name = nam
print(self.name,'constructed')
def party(self) :
self.x = self.x + 1
print(self.name,'party count',self.x)
# Code: http://www.py4e.com/code3/party.py</code></pre>
<p>Then, we can 'import' the <code>PartyAnimal</code> class in a new file and extend it as follows:</p>
<pre class="python"><code>from party import PartyAnimal
class CricketFan(PartyAnimal):
points = 0
def six(self):
self.points = self.points + 6
self.party()
print(self.name,"points",self.points)
s = PartyAnimal("Sally")
s.party()
j = CricketFan("Jim")
j.party()
j.six()
print(dir(j))
# Code: http://www.py4e.com/code3/party6.py</code></pre>
<p>When we are defining the <code>CricketFan</code> object, we indicate that we are extending the <code>PartyAnimal</code> class. This means that all of the variables (<code>x</code>) and methods (<code>party</code>) from the <code>PartyAnimal</code> class are inherited by the <code>CricketFan</code> class.</p>
<p>You can see that within the <code>six</code> method in the <code>CricketFan</code> class, we can call the <code>party</code> method from the <code>PartyAnimal</code> class. The variables and methods from the parent class are <em>merged</em> into the child class.</p>
<p>As the program executes, we can see that the <code>s</code> and <code>j</code> are independent instances of <code>PartyAnimal</code> and <code>CricketFan</code>. The <code>j</code> object has additional capabilities beyond the <code>s</code> object.</p>
<pre><code>Sally constructed
Sally party count 1
Jim constructed
Jim party count 1
Jim party count 2
Jim points 6
['__class__', '__delattr__', ... '__weakref__',
'name', 'party', 'points', 'six', 'x']</code></pre>
<p>In the <code>dir</code> output for the <code>j</code> object (instance of the <code>CricketFan</code> class) you can see that it both has the attributes and methods of the parent class as well as the attributes and methods that were added when the class was extended to create the <code>CricketFan</code> class.</p>
<h2 id="summary">Summary</h2>
<p>This is a very quick introduction to object-oriented programming that focuses mainly on terminology and the syntax of defining and using objects. Let's quickly review the code that we looked at in the beginning of the chapter. At this point you should fully understand what is going on.</p>
<pre class="python"><code>stuff = list()
stuff.append('python')
stuff.append('chuck')
stuff.sort()
print (stuff[0])
print (stuff.__getitem__(0))
print (list.__getitem__(stuff,0))
# Code: http://www.py4e.com/code3/party1.py</code></pre>
<p>The first line constructs a <code>list</code> <em>object</em>. When Python creates the <code>list</code> object, it calls the <em>constructor</em> method (named <code>__init__</code>) to set up the internal data attributes that will be used to store the list data. Due to <em>encapsulation</em> we neither need to know, nor need to care about how these internal data attributes are arranged.</p>
<p>We are not passing any parameters to the <em>constructor</em> and when the constructor returns, we use the variable <code>stuff</code> to point to the returned instance of the <code>list</code> class.</p>
<p>The second and third lines are calling the <code>append</code> method with one parameter to add a new item at the end of the list by updating the attributes within <code>stuff</code>. Then in the fourth line, we call the <code>sort</code> method with no parameters to sort the data within the <code>stuff</code> object.</p>
<p>Then we print out the first item in the list using the square brackets which are a shortcut to calling the <code>__getitem__</code> method within the <code>stuff</code> <em>object</em>. And this is equivalent to calling the <code>__getitem__</code> method in the <code>list</code> <em>class</em> passing the <code>stuff</code> object in as the first parameter and the position we are looking for as the second parameter.</p>
<p>At the end of the program the <code>stuff</code> object is discarded but not before calling the <em>destructor</em> (named <code>__del__</code>) so the object can clean up any loose ends as necessary.</p>
<p>Those are the basics and terminology of object oriented programming. There are many additional details as to how to best use object oriented approaches when developing large applications and libraries that are beyond the scope of this chapter.<a href="#fn3" class="footnoteRef" id="fnref3"><sup>3</sup></a></p>
<h2 id="glossary">Glossary</h2>
<dl>
<dt>attribute</dt>
<dd>A variable that is part of a class.
</dd>
<dt>class</dt>
<dd>A template that can be used to construct an object. Defines the attributes and methods that will make up the object.
</dd>
<dt>child class</dt>
<dd>A new class created when a parent class is extended. The child class inherits all of the attributes and methods of the parent class.
</dd>
<dt>constructor</dt>
<dd>An optional specially named method (<code>__init__</code>) that is called at the moment when a class is being used to construct an object. Usually this is used to set up initial values for the object.
</dd>
<dt>destructor</dt>
<dd>An optional specially named method (<code>__del__</code>) that is called at the moment just before an object is destroyed. Destructors are rarely used.
</dd>
<dt>inheritance</dt>
<dd>When we create a new class (child) by extending an existing class (parent). The child class has all the attributes and methods of the parent class plus additional attributes and methods defined by the child class.
</dd>
<dt>method</dt>
<dd>A function that is contained within a class and the objects that are constructed from the class. Some object-oriented patterns use 'message' instead of 'method' to describe this concept.
</dd>
<dt>object</dt>
<dd>A constructed instance of a class. An object contains all of the attributes and methods that were defined by the class. Some object-oriented documentation uses the term 'instance' interchangeably with 'object'.
</dd>
<dt>parent class</dt>
<dd>The class which is being extended to create a new child class. The parent class contributes all of its methods and attributes to the new child class.
</dd>
</dl>
<div class="footnotes">
<hr />
<ol>
<li id="fn1"><p>https://docs.python.org/3/library/html.parser.html<a href="#fnref1">↩</a></p></li>
<li id="fn2"><p>Cookie image copyright CC-BY https://www.flickr.com/photos/dinnerseries/23570475099<a href="#fnref2">↩</a></p></li>
<li id="fn3"><p>If you are curious about where the list class is defined, take a look at (hopefully the URL won't change) https://github.com/python/cpython/blob/master/Objects/listobject.c - the list class is written in a language called "C". If you take a look at that source code and find it curious you might want to explore a few Computer Science courses.<a href="#fnref3">↩</a></p></li>
</ol>
</div>
</body>
</html>
<?php if ( file_exists("../bookfoot.php") ) {
$HTML_FILE = basename(__FILE__);
$HTML = ob_get_contents();
ob_end_clean();
require_once "../bookfoot.php";
}?>