Table Of ContentMastering Object-Oriented
Python
Second Edition
Build powerful applications with reusable code using
OOP design patterns and Python 3.7
Steven F. Lott
BIRMINGHAM - MUMBAI
Mastering Object-Oriented Python
Second Edition
Copyright © 2019 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in
any form or by any means, without the prior written permission of the publisher, except in the case of brief
quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information
presented. However, the information contained in this book is sold without warranty, either express or
implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any
damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products
mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the
accuracy of this information.
Commissioning Editor: Richa Tripathi
Acquisition Editor: Chaitanya Nair
Content Development Editor: Zeeyan Pinheiro
Senior Editor: Afshaan Khan
Technical Editor: Ketan Kamble
Copy Editor: Safis Editing
Project Coordinator: Vaidehi Sawant
Proofreader: Safis Editing
Indexer: Manju Arasan
Production Designer: Jayalaxmi Raja
First published: April 2014
Second edition: June 2019
Production reference: 1130619
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.
ISBN 978-1-78953-136-7
www.packtpub.com
Packt.com
Subscribe to our online digital library for full access to over 7,000 books and videos,
as well as industry leading tools to help you plan your personal development and
advance your career. For more information, please visit our website.
Why subscribe?
Spend less time learning and more time coding with practical eBooks and
Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Fully searchable for easy access to vital information
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF
and ePub files available? You can upgrade to the eBook version at www.packt.com and
as a print book customer, you are entitled to a discount on the eBook copy. Get in
touch with us at customercare@packtpub.com for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for
a range of free newsletters, and receive exclusive discounts and offers on Packt books
and eBooks.
Contributors
About the author
Steven F. Lott has been programming since the 1970s, when computers were large,
expensive, and rare. As a contract software developer and architect, he has worked on
hundreds of projects, from very small to very large ones. He's been using Python to
solve business problems for over 10 years. His other titles with Packt include Python
Essentials, Mastering Object-Oriented Python, Functional Python Programming Second
Edition, Python for Secret Agents, and Python for Secret Agents II. Steven is currently a
technomad who lives in various places on the East Coast of the US. You can follow
him on Twitter via the handle @s_lott.
About the reviewers
Cody Jackson is a disabled military veteran, the founder of Socius Consulting – an IT
and business management consulting company in San Antonio – and a cofounder of
Top Men Technologies. He is currently employed at CACI International as the lead
ICS/SCADA modeling and simulations engineer. He has been involved in the tech
industry since 1994, when he joined the Navy as a nuclear chemist and Radcon
Technician. Prior to CACI, he worked at ECPI University as a computer information
systems adjunct professor. A self-taught Python programmer, he is the author of
Learning to Program Using Python and Secret Recipes of the Python Ninja. He holds an
Associate in Science degree, a Bachelor of Science degree, and a Master of Science
degree.
Hugo Solis is an assistant professor in the Physics Department at the University of
Costa Rica. His current research interests are computational cosmology, complexity,
cryptography, and the influence of hydrogen on material properties. He has vast
experience with languages, including C/C++ and Python for scientific programming.
He is a member of the Free Software Foundation and has contributed code to some
free software projects. He has also been a technical reviewer for Hands-On Qt for
Python Developers and Learning Object-Oriented Programming, and he is the author of
the Kivy Cookbook from Packt Publishing. Currently, he is in charge of the IFT, a Costa
Rican scientific nonprofit organization for the multidisciplinary practice of physics.
I'd like to thank Katty Sanchez, my beloved mother, for her support and vanguard
thoughts.
Packt is searching for authors like you
If you're interested in becoming an author for Packt, please visit
authors.packtpub.com and apply today. We have worked with thousands of
developers and tech professionals, just like you, to help them share their insight with
the global tech community. You can make a general application, apply for a specific
hot topic that we are recruiting an author for, or submit your own idea.
Table of Contents
Preface 1
Section 1: Tighter Integration Via Special
Methods
Chapter 1: Preliminaries, Tools, and Techniques 10
Technical requirements 11
About the Blackjack game 12
Playing the game 13
Blackjack player strategies 14
Object design for simulating Blackjack 14
The Python runtime and special methods 14
Interaction, scripting, and tools 15
Selecting an IDE 16
Consistency and style 17
Type hints and the mypy program 18
Performance – the timeit module 18
Testing – unittest and doctest 19
Documentation – sphinx and RST markup 21
Installing components 22
Summary 23
Chapter 2: The __init__() Method 24
Technical requirements 25
The implicit superclass – object 25
The base class object __init__() method 26
Implementing __init__() in a superclass 27
Creating enumerated constants 29
Leveraging __init__() via a factory function 31
Faulty factory design and the vague else clause 32
Simplicity and consistency using elif sequences 33
Simplicity using mapping and class objects 34
Two parallel mappings 35
Mapping to a tuple of values 36
The partial function solution 36
Fluent APIs for factories 37
Implementing __init__() in each subclass 38
Composite objects 40
Wrapping a collection class 41
Table of Contents
Extending a collection class 42
More requirements and another design 42
Complex composite objects 43
Complete composite object initialization 45
Stateless objects without __init__() 46
Some additional class definitions 47
Multi-strategy __init__() 50
More complex initialization alternatives 52
Initializing with static or class-level methods 54
Yet more __init__() techniques 55
Initialization with type validation 58
Initialization, encapsulation, and privacy 60
Summary 62
Chapter 3: Integrating Seamlessly - Basic Special Methods 63
Technical requirements 64
The __repr__() and __str__() methods 64
Simple __str__() and __repr__() 66
Collection __str__() and __repr__() 67
The __format__() method 68
Nested formatting specifications 71
Collections and delegating format specifications 71
The __hash__() method 72
Deciding what to hash 73
Inheriting definitions for immutable objects 75
Overriding definitions for immutable objects 78
Overriding definitions for mutable objects 80
Making a frozen hand from a mutable hand 82
The __bool__() method 84
The __bytes__() method 85
The comparison operator methods 88
Designing comparisons 90
Implementation of a comparison of objects of the same class 92
Implementation of a comparison of the objects of mixed classes 94
Hard totals, soft totals, and polymorphism 95
A mixed class comparison example 97
The __del__() method 100
The reference count and destruction 101
Circular references and garbage collection 102
Circular references and the weakref module 104
The __del__() and close() methods 106
The __new__() method and immutable objects 107
The __new__() method and metaclasses 109
Metaclass example – class-level logger 111
Summary 112
[ ii ]
Table of Contents
Chapter 4: Attribute Access, Properties, and Descriptors 114
Technical requirements 115
Basic attribute processing 115
Attributes and the __init__() method 117
Creating properties 118
Eagerly computed properties 121
The setter and deleter properties 123
Using special methods for attribute access 124
Limiting attribute names with __slots__ 126
Dynamic attributes with __getattr__() 127
Creating immutable objects as a NamedTuple subclass 128
Eagerly computed attributes, dataclasses, and __post_init__() 129
Incremental computation with __setattr__() 131
The __getattribute__() method 133
Creating descriptors 135
Using a non-data descriptor 138
Using a data descriptor 140
Using type hints for attributes and properties 143
Using the dataclasses module 145
Attribute Design Patterns 147
Properties versus attributes 148
Designing with descriptors 148
Summary 149
Chapter 5: The ABCs of Consistent Design 150
Technical requirements 150
Abstract base classes 151
Base classes and polymorphism 153
Callable 155
Containers and collections 155
Numbers 157
Some additional abstractions 158
The iterator abstraction 158
Contexts and context managers 159
The abc and typing modules 160
Using the __subclasshook__() method 162
Abstract classes using type hints 163
Summary, design considerations, and trade-offs 164
Looking forward 165
Chapter 6: Using Callables and Contexts 166
Technical requirements 167
Designing callables 167
Improving performance 169
Using memoization or caching 171
[ iii ]
Table of Contents
Using functools for memoization 172
Aiming for simplicity using a callable interface 173
Complexities and the callable interface 174
Managing contexts and the with statement 176
Using the decimal context 178
Other contexts 179
Defining the __enter__() and __exit__() methods 179
Handling exceptions 181
Context manager as a factory 182
Cleaning up in a context manager 183
Summary 185
Callable design considerations and trade-offs 185
Context manager design considerations and trade-offs 186
Looking forward 187
Chapter 7: Creating Containers and Collections 188
Technical requirements 189
ABCs of collections 189
Examples of special methods 191
Using the standard library extensions 191
The typing.NamedTuple class 193
The deque class 195
The ChainMap use case 197
The OrderedDict collection 198
The defaultdict subclass 199
The counter collection 201
Creating new kinds of collections 203
Narrowing a collection's type 204
Defining a new kind of sequence 205
A statistical list 206
Choosing eager versus lazy calculation 208
Working with __getitem__(), __setitem__(), __delitem__(), and slices 211
Implementing __getitem__(), __setitem__(), and __delitem__() 213
Wrapping a list and delegating 214
Creating iterators with __iter__() 217
Creating a new kind of mapping 218
Creating a new kind of set 220
Some design rationale 222
Defining the Tree class 223
Defining the TreeNode class 225
Demonstrating the binary tree bag 229
Design considerations and tradeoffs 230
Summary 231
Chapter 8: Creating Numbers 233
[ iv ]