Textbook Python Descriptors Understanding and Using The Descriptor Protocol 1St Edition Jacob Zimmerman Ebook All Chapter PDF

Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

Python Descriptors: Understanding and

Using the Descriptor Protocol 1st


Edition Jacob Zimmerman
Visit to download the full and correct content document:
https://textbookfull.com/product/python-descriptors-understanding-and-using-the-desc
riptor-protocol-1st-edition-jacob-zimmerman/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Python Descriptors 1st Edition Jacob Zimmerman

https://textbookfull.com/product/python-descriptors-1st-edition-
jacob-zimmerman/

Using Asyncio in Python Understanding Python s


Asynchronous Programming Features Caleb Hattingh

https://textbookfull.com/product/using-asyncio-in-python-
understanding-python-s-asynchronous-programming-features-caleb-
hattingh/

Introduction to Computation and Programming Using


Python with Application to Understanding Data Guttag

https://textbookfull.com/product/introduction-to-computation-and-
programming-using-python-with-application-to-understanding-data-
guttag/

Introduction to Computation and Programming Using


Python With Application to Understanding Data Second
Edition John V. Guttag

https://textbookfull.com/product/introduction-to-computation-and-
programming-using-python-with-application-to-understanding-data-
second-edition-john-v-guttag/
Supervised Learning with Python Concepts and Practical
Implementation Using Python 1st Edition Vaibhav Verdhan

https://textbookfull.com/product/supervised-learning-with-python-
concepts-and-practical-implementation-using-python-1st-edition-
vaibhav-verdhan/

Supervised Learning with Python: Concepts and Practical


Implementation Using Python Vaibhav Verdhan

https://textbookfull.com/product/supervised-learning-with-python-
concepts-and-practical-implementation-using-python-vaibhav-
verdhan/

Chemical and Biomedical Engineering Calculations Using


Python 1st Edition Jeffrey J. Heys

https://textbookfull.com/product/chemical-and-biomedical-
engineering-calculations-using-python-1st-edition-jeffrey-j-heys/

Computational Nuclear Engineering and Radiological


Science Using Python 1st Edition Ryan Mcclarren

https://textbookfull.com/product/computational-nuclear-
engineering-and-radiological-science-using-python-1st-edition-
ryan-mcclarren/

Introduction To Computing And Problem Solving Using


Python 1st Edition E. Balaguruswamy

https://textbookfull.com/product/introduction-to-computing-and-
problem-solving-using-python-1st-edition-e-balaguruswamy/
Python
Descriptors
Understanding and Using the
Descriptor Protocol

Second Edition

Jacob Zimmerman
Python Descriptors
Understanding and Using
the Descriptor Protocol
Second Edition

Jacob Zimmerman
Python Descriptors: Understanding and Using the Descriptor Protocol
Jacob Zimmerman
New York, USA

ISBN-13 (pbk): 978-1-4842-3726-7 ISBN-13 (electronic): 978-1-4842-3727-4


https://doi.org/10.1007/978-1-4842-3727-4
Library of Congress Control Number: 2018960194
Copyright © 2018 by Jacob Zimmerman
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or
part of the material is concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way,
and transmission or information storage and retrieval, electronic adaptation, computer software,
or by similar or dissimilar methodology now known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark
symbol with every occurrence of a trademarked name, logo, or image we use the names, logos,
and images only in an editorial fashion and to the benefit of the trademark owner, with no
intention of infringement of the trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if
they are not identified as such, is not to be taken as an expression of opinion as to whether or not
they are subject to proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of
publication, neither the authors nor the editors nor the publisher can accept any legal
responsibility for any errors or omissions that may be made. The publisher makes no warranty,
express or implied, with respect to the material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Steve Anglin
Development Editor: Matthew Moodie
Coordinating Editor: Mark Powers
Cover designed by eStudioCalamar
Cover image designed by Freepik (www.freepik.com)
Distributed to the book trade worldwide by Springer Science+Business Media New York, 233
Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail
[email protected], or visit www.springeronline.com. Apress Media, LLC is a
California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc
(SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail [email protected]; for reprint, paperback, or
audio rights, please email [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook
versions and licenses are also available for most titles. For more information, reference our Print
and eBook Bulk Sales web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is
available to readers on GitHub via the book’s product page, located at www.apress.com/
9781484237267. For more detailed information, please visit http://www.apress.com/
source-code.
Printed on acid-free paper
Table of Contents
About the Author��������������������������������������������������������������������������������vii

About the Technical Reviewer�������������������������������������������������������������ix


Acknowledgments�������������������������������������������������������������������������������xi
Introduction���������������������������������������������������������������������������������������xiii

Part I: About Descriptors�������������������������������������������������������������1


Chapter 1: What Is a Descriptor?����������������������������������������������������������3
Data Descriptors versus Non-Data Descriptors����������������������������������������������������4
The Use of Descriptors by Python�������������������������������������������������������������������������4
Summary��������������������������������������������������������������������������������������������������������������5

Chapter 2: The Descriptor Protocol������������������������������������������������������7


The __get__(self, instance, owner) Method����������������������������������������������������������7
The __set__(self, instance, value) Method��������������������������������������������������������� 8
The __delete__(self, instance) Method�����������������������������������������������������������������9
Summary������������������������������������������������������������������������������������������������������������10

Chapter 3: What Are Descriptors Good For?���������������������������������������11


Pros of Python Descriptors���������������������������������������������������������������������������������11
Encapsulation������������������������������������������������������������������������������������������������11
Reuse of Read/Write Patterns�����������������������������������������������������������������������12
Writing for the Class Level�����������������������������������������������������������������������������13

iii
Table of Contents

Cons of Python Descriptors���������������������������������������������������������������������������������13


Encapsulation������������������������������������������������������������������������������������������������13
Can Be Difficult To Write��������������������������������������������������������������������������������14
Additional Objects�����������������������������������������������������������������������������������������14
Summary������������������������������������������������������������������������������������������������������������14

Chapter 4: Descriptors in the Standard Library����������������������������������15


The property Class����������������������������������������������������������������������������������������������16
The classmethod Descriptor�������������������������������������������������������������������������������18
The staticmethod Descriptor�������������������������������������������������������������������������������19
Regular Methods�������������������������������������������������������������������������������������������������19
Summary������������������������������������������������������������������������������������������������������������20

Chapter 5: Attribute Access and Descriptors�������������������������������������21


Instance Access��������������������������������������������������������������������������������������������������22
Set and Delete Calls��������������������������������������������������������������������������������������������27
The Reasoning Behind Data versus Non-Data Descriptors��������������������������������28
Summary������������������������������������������������������������������������������������������������������������28

Part II: Making Descriptors�������������������������������������������������������29


Chapter 6: Which Methods Are Needed?��������������������������������������������31
When __get__() Is Called Without an instance Argument����������������������������������32
Raise Exception or Return self����������������������������������������������������������������������32
“Unbound” Attributes������������������������������������������������������������������������������������33
Summary������������������������������������������������������������������������������������������������������������37

Chapter 7: Storing the Attributes�������������������������������������������������������39


Class-Level Storage��������������������������������������������������������������������������������������������39
Storing Data on the Descriptor����������������������������������������������������������������������������40
Storing on the Instance Dictionary����������������������������������������������������������������46

iv
Table of Contents

Asking for the Location����������������������������������������������������������������������������������48


Indirectly Asking for the Location�����������������������������������������������������������������������50
Name Mangling���������������������������������������������������������������������������������������������51
Store the Original and the Mangled���������������������������������������������������������������54
Summary������������������������������������������������������������������������������������������������������������57

Chapter 8: Read-Only Descriptors������������������������������������������������������59


Set-Once Descriptors������������������������������������������������������������������������������������������60
Secret-Set Descriptors����������������������������������������������������������������������������������������61
Forced-Set Descriptors���������������������������������������������������������������������������������������62
Class Constants��������������������������������������������������������������������������������������������������63
Summary������������������������������������������������������������������������������������������������������������65

Chapter 9: Writing__delete__()�����������������������������������������������������������67
Summary������������������������������������������������������������������������������������������������������������68

Chapter 10: Descriptors Are Classes Too��������������������������������������������69


Inheritance����������������������������������������������������������������������������������������������������������69
More Methods�����������������������������������������������������������������������������������������������������70
Optional/Default Parameters�������������������������������������������������������������������������������70
Descriptors on Descriptors���������������������������������������������������������������������������������70
Passing an Instance Around��������������������������������������������������������������������������������71
Descriptors Just Abstract Method Calls��������������������������������������������������������������72
Summary������������������������������������������������������������������������������������������������������������72

Chapter 11: Reusing the Wheel����������������������������������������������������������73


Storage Solutions������������������������������������������������������������������������������������������������73
Read-Only Solutions��������������������������������������������������������������������������������������������76
Simple Unbound Attributes���������������������������������������������������������������������������������78
Summary������������������������������������������������������������������������������������������������������������80

v
Table of Contents

Chapter 12: Instance-Level Descriptors���������������������������������������������81


Properties in Other Languages���������������������������������������������������������������������������81
Back to Python����������������������������������������������������������������������������������������������������82
Attempt 1�������������������������������������������������������������������������������������������������������82
Attempt 2�������������������������������������������������������������������������������������������������������83
Attempt 3�������������������������������������������������������������������������������������������������������85
Attempt 4�������������������������������������������������������������������������������������������������������85
Example��������������������������������������������������������������������������������������������������������������87
Go Nuts���������������������������������������������������������������������������������������������������������������88

Chapter 13: Other Uses of Descriptors In the World���������������������������89


SQLAlchemy��������������������������������������������������������������������������������������������������������89
Jigna�������������������������������������������������������������������������������������������������������������������90
Elk�����������������������������������������������������������������������������������������������������������������������90
Validators������������������������������������������������������������������������������������������������������������91
Summary������������������������������������������������������������������������������������������������������������91

Bibliography���������������������������������������������������������������������������������������93

Index���������������������������������������������������������������������������������������������������95

vi
About the Author
Jacob Zimmerman is a blogger, gamer (tabletop more so than video
games), and programmer who was born and raised in Wisconsin. He has a
twin brother who could also be considered to have all those traits.
Jacob has his own programming blog that focuses on Java, Kotlin,
and Python programming, called “Programming Ideas with Jake”. He also
writes for a gaming blog with his brother-in-law called the “Ramblings of
Jacob and Delos”.
His brother writes a JavaScript blog called JoeZimJS and works with
his best friend on a gaming YouTube channel called “Bork & Zim Gaming,”
which Jacob helps out with on occasion.
Programming Ideas with Jake
http://programmingideaswithjake.wordpress.com/
Ramblings of Jacob and Delos
http://www.ramblingsofjacobanddelos.com/
JoeZimJS
http://www.joezimjs.com

vii
About the Technical Reviewer
Michael Thomas has worked in software development for more than 20
years as an individual contributor, team lead, program manager, and vice
president of engineering. Michael has more than 10 years of experience
working with mobile devices. His current focus is in the medical sector,
using mobile devices to accelerate information transfer between patients
and health care providers.

ix
Acknowledgments
In order to be sure that I got everything right—it would really suck for a
“comprehensive guide” to be missing a big chunk of functionality or to get
anything wrong—I enlisted the help of some Python experts on the first
edition. In return for their help, I let them introduce themselves to you
here. That’s not all I did in return, but it’s all you’re going to see :)
Emanuel Barry is a self-taught Python programmer who loves pushing
the language to its limits as well as exploring its darkest corners. He has to
do a lot of proofreading and editing for a local non-for-profit organization,
and decided to combine his love of Python and knowledge sharing with
his background in proofreading to help make this book even better. He can
often be found in the shadows of the mailing lists or the issue tracker, as
well as the Python IRC channel, as Vgr.
Chris Angelico has played around with Python since the late 90s, getting
more serious with the language in the mid 2000s. As a PEP Editor and active
participant in the various mailing lists, he keeps well up to date with what’s
new and upcoming in the language and also shares that knowledge with
fledgling students in the Thinkful tutoring/mentoring program. When not
coding in Python, he is often found wordsmithing for a Dungeons & Dragons
campaign, or exploring the linguistic delights of Alice in Wonderland and
similar works. If you find a subtle Alice reference in this text, blame him!

https://github.com/Rosuav

Kevin Mackay is a software engineer who has been programming in


Python since 2010 and is currently working at BBC, improving the Taster
platform. He is enthusiastic about open source software and occasionally
contributes to the 3D graphics application, Blender. He can be found on the
Python IRC channel as yakca or hiking on a mountain somewhere in Scotland.

xi
Introduction
Python is a remarkable language with many surprisingly powerful features
baked into it. Generators, metaclasses, and decorators are some of those,
but this book is all about descriptors.

Code Samples
All code samples are written in Python 3, since that is the most recent
version, but all the ideas and principles taught in this book apply to Python
2 as well, as long as you’re using new style classes.

The Descriptor Tools Library


Written alongside this book was a library, called descriptor-tools, which
can be installed with pip. It contains the fruition of a lot of the ideas and
helpers to make it easier to implement them all. It’s an open source project
with a public GitHub repository.1

Note Superscript letters like the one at the end of the previous line
are in reference to the bibliography at the back of the book, which
includes URLs to the referenced site.

xiii
Introduction

Conventions in This Book


When the text mentions “class” and “instance” in a general sense, they
refer to a class that has a descriptor attribute and to instances of such
classes, respectively. All other classes and instances will be referred to
more specifically.

New in the 2nd Edition


The 2nd edition is an update including new features of Python as well as
new ideas to learn. One of the new things is incredibly important if this
book wants to maintain the status of “comprehensive” guide that it strives
for. This important addition is about the addition of __set_name__() to the
descriptor protocol in Python 3.6. You can read about this in Chapter 7,
“Storing the Attributes”.
Another addition is an idea that was inspired by looking into the
__set_name__() addition to the protocol, which you’ll see just after the
section on that addition. Also, I added a chapter on creating instance-level
descriptors, which were added to descriptor-tools well before this edition
really got started.
The next thing is actually a change, not an addition. Since writing
the first book, I found out about the built-in function vars(). Calling
vars(obj) is equivalent to obj.__dict__, but is more Pythonic. Kind of
like calling len(obj) instead of obj.__len__(). So the code examples
have been updated to use vars(). Any remaining references to __dict__
are purposeful.
Pretty much everything else new in this edition is just cleaning up the
language to be more legible.

xiv
PART I

About Descriptors
Part I is a deep explanation of what descriptors are, how they work, and
how they’re used. It gives enough information that you should be able to
look at any descriptor and understand how it works and why it works that
way, assuming the writer of the code made the code legible enough.
Creating your own descriptors isn’t difficult once you have the
information from Part I, but little to no guidance is given to help with
it. Instead, Part II covers that with a bunch of options for creating new
descriptors, as well as tips for avoiding common mistakes.
CHAPTER 1

What Is a Descriptor?
Put very simply, a descriptor is a class that can be used to call a method
with simple attribute access, but there’s obviously more to it than that. It’s
difficult to explain beyond that without digging a little into how descriptors
implemented. So, here’s a high-level view of the descriptor protocol.
A descriptor implements at least one of these three methods:
__get__(), __set__(), or __delete__(). Each of those methods has a list
of parameters needed, which will be discussed a little later, and each is
called by a different sort of access of the attribute the descriptor represents.
Doing simple a.x access will call the __get__() method of x; setting the
attribute using a.x = value will call the __set__() method of x; and using
del a.x will call, as expected, the __delete__() method of x.

Note Since version 3.6, there’s another method that descriptors


can take advantage of, called __set_name__(), but using just
that method doesn’t make it a descriptor the way any of the other
three will. This method will be mostly ignored for a while, since it
doesn’t have as big a role into how descriptors work. It will only be
mentioned where most relevant.

As stated, only one of the methods needs to be implemented in


order to be considered a descriptor, but any number of them can be
implemented. And, depending on descriptor type and on which methods

© Jacob Zimmerman 2018 3


J. Zimmerman, Python Descriptors, https://doi.org/10.1007/978-1-4842-3727-4_1
Chapter 1 What Is a Descriptor?

are implemented, not implementing certain methods can restrict certain


types of attribute access or provide interesting alternative behaviors for
them. There are two types of descriptors based on which sets of these
methods are implemented: data and non-data.

 ata Descriptors versus Non-Data


D
Descriptors
A data descriptor implements at least __set__() or __delete__(), but
can include both. Data descriptors also often include __get__() since it’s
rare to want to set something without also being able to get it too. You can
get the value, even if the descriptor doesn’t include __get__(), but it’s
either roundabout or the descriptor writes it to the instance. That will be
discussed more later.
A non-data descriptor only implements __get__(). If it adds a __set__()
or __delete__() method, it becomes a data descriptor.
Unfortunately, the PyPy interpreter (up to version 2.4.0) gets this a little
bit wrong. It doesn’t take __delete__() into consideration until it knows
that it’s a data descriptor, and PyPy doesn’t believe something is a data
descriptor unless __set__() is implemented. Luckily, since a huge majority
of data descriptors implement __set__(), this rarely becomes a problem.
It may seem like the distinction is pointless, but it is not. It comes into
play upon attribute lookup. This will be discussed more later, but basically,
the distinction is the types of uses it provides.

The Use of Descriptors by Python


It is worth noting that descriptors are an inherent part of how Python
works. Python is known to be a multi-paradigm language, and as such
supports paradigms such as functional programming, imperative

4
Chapter 1 What Is a Descriptor?

programming, and object-oriented programming. This book does not


attempt to go into depth about the different paradigms; only the object-­
oriented programming paradigm will be observed. Descriptors are used
implicitly in Python for the language’s object-oriented mechanisms. As will
be explained shortly, methods are implemented using descriptors. As you
may guess from reading this, it is thanks to descriptors that object-oriented
programming is possible in Python. Descriptors are very powerful and
advanced, and this book aims to teach Python programmers how to use
them fully.

Summary
As you have seen, descriptors occupy a large part of the Python language, as
they can replace attribute access with method calls, and even restrict which
types of attribute access is allowed. Now that you have a broad idea of how
descriptors are implemented as well as their use by the language, we will
dig a little deeper yet, gaining a better understanding of how they work.

5
CHAPTER 2

The Descriptor
Protocol
In order to get a better idea of what descriptors are good for, let’s finish
showing the full descriptor protocol. It’s time to see the full signatures of
the protocol’s methods and what the parameters are.

The __get__(self, instance, owner) Method


This method is clearly the method for retrieving whatever data or object the
descriptor is meant to maintain. Obviously, self is a parameter, since it’s a
method. Also, it receives instance and/or owner. We’ll start with owner.
owner is the class that the descriptor is accessed from, or else the
class of the instance it’s being accessed from. When you make the call
A.x (A being a class), and x is a descriptor object with __get__(), it’s called
with an owner with the instance set to None. So the lookup gets effectively
transformed into A.__dict__['x'].__get__(None, A). This lets the
descriptor know that __get__() is being called from a class, not an instance.
owner is also often written to have a default value of None, but that’s largely
an optimization that only built-in descriptors take advantage of.
Now, onto the last parameters. instance is the instance that the
descriptor is being accessed from, if it is being accessed from an instance.
As previously stated, if None is passed into instance, the descriptor knows

© Jacob Zimmerman 2018 7


J. Zimmerman, Python Descriptors, https://doi.org/10.1007/978-1-4842-3727-4_2
Chapter 2 The Descriptor Protocol

that it’s being called from the class level. But, if instance is not None, then it
tells the descriptor which instance it’s being called from. So an a.x call will
be effectively translated to type(a).__dict__['x'].__get__(a, type(a)).
Notice that it still receives the instance’s class. Notice also that the call still
starts with type(a), not just a, because descriptors are stored on classes.
In order to be able to apply per-instance as well as per-class functionality,
descriptors are given instance and owner (the class of the instance). How
this translation and application happens will be discussed later.
Remember—and this applies to __set__() and __delete__() as
well—self is an instance of the descriptor itself. It is not the instance that
the descriptor is being called from; the instance parameter is the instance
the descriptor is being called from. This may sound confusing at first, but
don’t worry if you don’t understand for now—everything will be explained
further.
The __get__() method is the only one that bothers to get the class
separately. That’s because it’s the only method on non-data descriptors,
which are generally made at a class level. The built-in decorator
classmethod is implemented using descriptors and the __get__()
method. In that case, it will use the owner parameter alone.

The __set__(self, instance, value) Method


As mentioned, __set__() does not have an owner parameter that accepts
a class. __set__() does not need it, since data descriptors are generally
designed for storing per-instance data. Even if the data is being stored on a
per-class level, it should be stored internally without needing to reference
the class.
self should be self-explanatory now; the next parameter is instance.
This is the same as it is in the __get__() method. In this case, though,
your initial call is a.x = someValue, which is then translated into
type(a).__dict__['x'].__set__(a, someValue).

8
Chapter 2 The Descriptor Protocol

The last parameter is value, which is the value the attribute is being
assigned.
One thing to note: when setting an attribute that is currently a
descriptor from the class level, it will replace the descriptor with whatever
is being set. For example, A.x = someValue does not get translated to
anything; someValue replaces the descriptor object stored in x. To act on
the class, see the following note.

The __delete__(self, instance) Method


After having learned about the __get__() and __set__() methods,
__delete__() should be easy to figure out. self and instance are the
same as in the other methods, but this method is invoked when del a.x is
called and is translated to type(a).__dict__['x'].__delete__(a).
Do not accidentally name it __del__(), as that won’t work as intended.
__del__() would be the destructor of the descriptor instance, not of the
attribute stored within.
It must be noted that, again, that __delete__() does not work from the
class level, just like __set__(). Using del from the class level will remove
the descriptor from the class’ dictionary rather than calling the descriptor’s
__delete__() method.

Note If you want a descriptor’s __set__() or __delete__()


methods to work from the class level, that means that the descriptor
must be created on the class’ metaclass. When doing so, everything
that refers to owner is referring to the metaclass, while a reference
to instance refers to the class. After all, classes are just instances
of metaclasses. The section on metadescriptors will explain that in
greater detail.

9
Chapter 2 The Descriptor Protocol

Summary
That’s the sum total of the descriptor protocol. Having a basic idea of how
it works, you’ll now get a high-level view of the types of things that can be
done with descriptors.

10
CHAPTER 3

What Are Descriptors


Good For?
Nothing is perfect in this world, and Python’s descriptors are no exception.
Descriptors allow you to do some pretty cool things, but those cool things
come at a cost. Here, we discuss the good and the bad.

Pros of Python Descriptors


Obviously we’re going to go over the good things about descriptors.
Would there be an entire book about them if they couldn’t be considered a
good thing?

E ncapsulation
One of the most useful aspects of descriptors is that they encapsulate
data so well. With descriptors, you can access an attribute the simple way
using attribute access notation (a.x) while having more complex actions
happen in the background. For example, a Circle class might have radius,
diameter, circumference, and area all available as if they were attributes,
but since they’re all linked, you only need to store one (we’ll use the radius
for the example) and calculate the others based on it. But from the outside,
they all look like attributes stored on the object.

© Jacob Zimmerman 2018 11


J. Zimmerman, Python Descriptors, https://doi.org/10.1007/978-1-4842-3727-4_3
Chapter 3 What Are Descriptors Good For?

Reuse of Read/Write Patterns


Using specialized descriptors, you can reuse code that you used with
reading and/or writing of attributes. These can be used for repetitious
attributes within the same class or attribute types shared by other classes
as well. Some examples of reusable patterns are described in the following
sections.

Lazy Instantiation
You can use descriptors to define a really simple syntax for lazily
instantiating an attribute. There will be code provided for a nice lazy
attribute implementation later in the book.
In the Circle example, the non-radius attributes, after having their
caches invalidated, don’t need to calculate their values right away; they
could wait until they’re needed. That’s laziness.

Validation
Many descriptors are written simply to make sure that data being passed
in conforms to the class’ or attribute’s invariants. Such descriptors can
usually be designed as handy decorators, too.
Again with the Circle example: all of those attributes should be
positive, so all the descriptors could also make sure the value being set is
positive.

Triggering Actions
Descriptors can be used to trigger certain actions when the attribute is
accessed. For example, the observer pattern can be implemented in a
per-attribute sense to trigger calls to the observer whenever an attribute is
changed.

12
Chapter 3 What Are Descriptors Good For?

Last Circle example: all the “attributes” are based on the radius
calculated lazily. In order to keep from having to calculate them every
time, you could cache the result. Then, whenever one of them changes,
it could trigger invalidating all the others’ caches.

Writing for the Class Level


Because descriptors are stored at the class scope instead of the instance
scope, it allows you to do more robust things at the class level. For instance,
descriptors make classmethod and staticmethod work, which will be
explained in the next chapter.

Cons of Python Descriptors


As great as descriptors are, they come at a cost, just like just about
everything else in programming.

Encapsulation
Wait… encapsulation was a pro. How can it also be a con? The problem
is that you can hide incredible amounts of complexity behind something
that just looks like attribute use. With getters and setters, the user at least
sees that there’s a function being called, and plenty can happen in a single
function call. But the user won’t necessarily expect that what is seemingly
attribute access is causing something else to happen, too. Most of the time,
this isn’t a problem, but it can get in the user’s way of trying to debug any
problems, since clearly that code can’t be a problem.

13
Chapter 3 What Are Descriptors Good For?

Can Be Difficult To Write


It can be easy for the mind to get all twisted up when it comes to thinking
about the fact that descriptors are stored at the class level, but are usually
for dealing with attributes at the instance level. Besides that, there are
a lot of considerations and common pitfalls to deal with when deciding
how to save the represented attribute, whether you decide to do it on the
descriptor or on the the object that the attribute is for. The descriptor-tools
library was created specifically because of this.

Additional Objects
Because descriptors add another layer of indirection/abstraction to the
mix, they also add at least one additional object in memory, along with at
least one additional call stack level. In most cases, it’ll be more than one of
each. This adds bloat that could at least be partially mitigated using getters
and setters.

Summary
Descriptors are awesome, allowing for a variety of nice features that are
good at hiding their complexity from users of your code, but you should
definitely be aware that the power comes with cost.

14
CHAPTER 4

Descriptors in the
Standard Library
There are three basic, well-known descriptors that come with Python:
property, classmethod, and staticmethod. There’s also a fourth one that
you use all the time, but are less likely to know is a descriptor.
Of all the descriptors being shown in this chapter, it’s possible that
you only knew of property as a descriptor. Plenty of people even learn
the basics of descriptors from it, but a lot of people don’t know that
classmethod and staticmethod are descriptors. They feel like super
magical constructs built into the language that no one could reproduce in
pure Python. Once someone has an understanding of descriptors, though,
their basic implementation becomes relatively obvious. In fact, example
code will be provided for all three in simplified, pure Python code.
Lastly, it will be shown that all methods are actually implemented
with descriptors. Normal methods are actually done “magically,” since the
descriptor creation is implicit, but it’s still not entirely magical because it’s
done using a language construct the anyone could create.
What I find really interesting is that the first three are all function
decorators, which are another really awesome feature of Python that
deserves its own book, even though they’re way simpler.

© Jacob Zimmerman 2018 15


J. Zimmerman, Python Descriptors, https://doi.org/10.1007/978-1-4842-3727-4_4
Chapter 4 Descriptors in the Standard Library

The property Class


This book doesn’t include instructions for how to use the property class
and decorator; it is focused on understanding and creating descriptors.
The official documentation for using property can be found in Python’s
documentation2.
Of all the descriptors out there, property is likely the most versatile.
This is because it doesn’t really do anything on its own, but rather allows
the users to inject their wanted functionality into it by providing their own
getters, setters, and deleters.
To get a better idea of how it works, here is a simplified pure Python
implementation of property.

class property:
    def __init__(self, fget=None, fset=None, fdel=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel

    def __get__(self, instance, owner):


        if instance is None:
            return self
        elif self.fget is None:
            raise AttributeError("unreadable attribute")
        else:
            return self.fget(instance)

    def __set__(self, instance, value):


        if self.fset is None:
            raise AttributeError("can't set attribute")
        else:
            self.fset(instance, value)

16
Chapter 4 Descriptors in the Standard Library

    def __delete__(self, instance):


        if self.fdel is None:
            raise AttributeError("can't delete attribute")
        else:
            self.fdel(instance)

    def getter(self, fget):


        return type(self)(fget, self.fset, self.fdel)

    def setter(self, fset):


        return type(self)(self.fget, fset, self.fdel)

    def deleter(self, fdel):


        return type(self)(self.fget, self.fset, fdel)

As you can now see, the property class has almost no real functionality
of its own; it simply delegates to the functions given to it. When a function
is not provided for a certain method to delegate to, property assumes that
it is a forbidden action and raises an AttributeError with an appropriate
message.
A nice thing about the property class is that it largely just accepts
methods. Even its constructor, which can be given all three methods at
once, is capable of being called with just one, or even none. Because of
this, the constructor and other methods can be used as decorators in a
very convenient syntax. Check out the documentation2 to learn more
about it.
Omitted from this code example is the doc functionality, where it sets
its own __doc__ property based on what is passed in through __init__()’s
doc parameter or using __doc__ from fget if nothing is given. Also omitted
is the code that sets other attributes on property, such as __name__, in
order to help it appear even more like a simple attribute. They did not
seem important enough to worry about, since the focus was more on the
main functionality.

17
Chapter 4 Descriptors in the Standard Library

The classmethod Descriptor


classmethod is another descriptor that can be used as a decorator, but,
unlike property, there’s no good reason not to use it as one. classmethod
is an interesting concept that doesn’t exist in many other languages
(if any). Python’s type system, which uses classes as objects, makes
classmethods easy and worthwhile to make.
Here’s the Python code for classmethod.

class classmethod:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):


        return functools.partial(self.func, owner)

That’s all there is to it. classmethod is a non-data descriptor, so it only


implements __get__(). This __get__() method completely ignores the
instance parameter because, as “class” in the name implies, the method
has nothing to do with an instance of the class and only deals with the
class itself. What’s really nice is the fact that this can still be called from an
instance without any issues.
Why does the __get__() method return a functools.partial object
with the owner passed in, though? To understand this, think about the
parameter list of a function marked as a classmethod. The first parameter
is the class parameter, usually named cls. This class parameter is filled in
the call to partial so that the returned function can be called with just the
arguments the user wants to explicitly provide. The true implementation
doesn’t use partial, but works similarly.
Again, the code that sets __name__, __doc__, etc. is omitted to show
only how the main functionality works.

18
Chapter 4 Descriptors in the Standard Library

The staticmethod Descriptor


A method marked with staticmethod is strange in that it’s a method that
is really just a function, but it is “attached” to a class. Being part of the class
doesn’t do anything other than show users that it is associated with that
class and giving it a more specific namespace. Also, interestingly, because
staticmethod and classmethod are implemented using descriptors,
they’re inherited by subclasses.
The implementation of staticmethod is even simpler than that of
classmethod; it just accepts a function and then returns it when __get__()
is called.

class staticmethod:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):


        return self.func

Regular Methods
Remember that it was stated earlier that regular methods implicitly use
descriptors as well. In fact, all functions can be used as methods. This is
because functions are non-data descriptors as well as callables.
Here is a Python implementation that roughly shows how a function
looks.

class function:
    def __call__(self, *args, **kwargs):
        # do something

19
Another random document with
no related content on Scribd:
But that isn’t it, after all. She is so charmingly frank. I think that’s it.
It’s unusual in a child.”
“Yes, indeed,” agreed Mrs. Thornburg. “Unusual in any one, I should
say.”
“Why, perhaps it is,” agreed Baron simply. He was not a little puzzled
by something in Mrs. Thornburg’s manner.
“And why don’t you want to keep her?” she wanted to know.
“We meant to. But it turns out that she and my mother are—well,
antagonistic.”
“That’s unfortunate, isn’t it? Please pardon me—you see, I’m really
handicapped. But—what kind of woman is your mother?” She put the
question so softly that it did not seem offensive.
Baron hesitated. “Perhaps it will explain if I say that she is elderly?
There haven’t been any children in the house for a good many years.
She believes—what is the familiar saying?—that children ought to be
seen and not heard.”
Mrs. Thornburg hesitated. “That wouldn’t be quite the reason,” she
said. “Your mother is—is orthodox, I suspect, in her friendships and
ways. I’m sure you see what I mean.”
“Yes,” admitted Baron. “I think you are getting closer to the facts than
I did.”
A pretty, delicate hue warmed the woman’s face, and her voice
softened almost to tenderness. “I think I know,” she went on. “The
little girl of the stage, out of some unknown place in Bohemia—she
must seem quite disturbing, hopelessly out of harmony....”
“You put the case much better than I did. Yet you know all that’s
scarcely fair to Bonnie May. She’s not really bold and impertinent, in
the usual sense of those words. She hasn’t had the kind of training
other children have. She has never associated with other children.
You can see that instantly. She assumes that she has the same right
to her opinion that older people have to theirs. She never means to
offend. I have an idea she’s really quite affectionate. I have an idea if
you once won her over——”
Mrs. Thornburg turned toward her husband and leaned forward in
her chair, her eyes filled with a soft, generous impulse. When she
spoke her voice vibrated with feeling.
“Bring her home!” she said.
Baron fancied there was an expression of triumph in the manager’s
bearing. “You mean now—to-night?” he asked.
“Why not to-night? I’m eager to have her; really eager, now that I’ve
decided.”
“It’s quite simple,” declared Thornburg. “I suppose you’ll have to—to
get a few things ready?”
Her whole being became tremulous—she who had had no children
of her own, and who knew nothing about them. “Nothing to-night, to
speak of. To-morrow....” She clasped her hands and looked into
vacancy, as if visions were coming to her.
But Thornburg was already in an adjoining room at the telephone,
ordering his machine.
Baron regarded Mrs. Thornburg thoughtfully. He was surprised and
touched by her intensity. Then she looked at him, mutely appealing.
There was a long moment during which two minds tried to meet
across a barrier of emotion and a lack of mutual knowledge. Then
Mrs. Thornburg spoke.
“You know,” she explained, “we’ve both been disappointed, deeply
disappointed, because we hadn’t any of our own.”
When Thornburg’s automobile stopped before the Baron mansion,
half an hour later that evening, and the manager and Baron got out,
something happened.
Mrs. Baron, her gray hair stirring slightly in the spring breeze, stood
on the front steps for all the world like an alert sentinel.
“Well, Victor?” she demanded, as her son advanced toward her. Her
voice was sternly challenging.
“This gentleman has come to take Bonnie May away,” replied her
son. He derived a certain satisfaction from her disturbed state.
“Where to?”
“To her new home, with Mr. and Mrs. Thornburg.”
“Do you mean you’ve brought that machine to take her away to-
night?”
“Why, yes—certainly.”
“Well, you can just send it away. You won’t need it to-night.”
“I don’t believe I understand, mother!”
Baron had approached the lowest step and Thornburg had taken a
position close to him. Mrs. Baron, from her superior height, frowned
down upon them as if they were two kidnappers who must be held at
bay.
“You probably don’t,” replied Mrs. Baron. “It isn’t necessary that you
should, either. But you’ll grasp my meaning when I tell you that child
shall not be taken away in the dead of night, as if she were being
stolen, and she shall not leave this house until she has been
decently clothed and made ready to go. I never heard of such an
outrageous thing in my life.” She turned with fear, yet with severity,
toward Thornburg. When she spoke again it might have seemed that
she regarded the manager as a kind of trained wolf over whom her
son might possess an influence. “Victor, tell him to go away!” she
commanded. “When I want him to come back I’ll let you know.”
She turned with the air of a queen who had been affronted. In an
instant she had disappeared. The door had been quite unmistakably
slammed behind her.
CHAPTER XII
RELATES TO THE PLAYING OF PARTS

Much light is thrown upon the character of Victor Baron when it is


said that he was the kind of young man who likes to sit in an attic
when the rain is falling.
Such a young man may possess many high virtues, certainly; but he
can scarcely hope to escape occasional contact with what is called
the world’s cold shoulder. He is clearly not the sort of person who
knows what magic there is in the matter of percentages and other
such progressive and acquisitive sciences.
We now encounter this peculiar young man in his attic room, on an
afternoon when the rain was falling steadily.
Days had passed since Mrs. Baron had driven the manager,
Thornburg, from her front door. Something like a fixed status in the
case of Bonnie May had been brought about. Seemingly, she had
become a permanent member of the Baron household.
Yet Baron was not happy. Having performed his duty in solving one
problem, he had now passed on to another, an older problem.
There was the fact of his aimless existence staring him in the face;
the fact that he had been home from the university over a year now,
and that as yet he had chosen no plough to the handles of which he
meant to set his hands.
He did a little newspaper writing when the spirit moved him: articles
and reviews which were often quite cordially accepted—and
sometimes even urgently solicited—but which were still subjected to
a measuring process in the accounting room of the newspaper
offices, and which were only meagrely profitable.
To be sure, his needs were quite simple. He made no contributions
to the up-keep of the household. He kept his tailor’s bills paid with a
reasonable degree of promptitude. Usually, too, he had funds
enough for books and other means of recreation. Still, there were
occasions when he had to go to his mother for assistance, and this
practise he was compelled to contemplate with utter disfavor.
It is true that he never asked his mother for Money. The Barons
pronounced the word money as if it were spelled with a capital letter,
like certain other more or less unsavory names—Lucretia Borgia,
New Caledonia, Christian Science, Prussianism, or Twilight Sleep.
He used to ask her, when need arose, if she had any street-car-fare
lying about. And she would put her index-finger to her forehead and
meditate, and then remember suddenly that there was some in her
work-basket on the centre-table, or under something or other on the
sideboard. A burglar would have had a discouraging experience in
the mansion; not because there was never anything to steal, but
because what money there was was always placed lightly in such
unpromising places.
“I really ought to get down to business,” concluded Baron, sitting in
his attic—though the phrase was inept, since business was another
word which the Barons pronounced as if it were spelled with a capital
letter.
The place was depressingly quiet. The houseman, Thomason, might
be in his room, which adjoined Baron’s; but Thomason never made
any noise. He was almost uncannily quiet at all times. The door
between the two rooms was never opened. Both opened upon the
hall, and when Thomason wished to attend to his duties he
descended to the floor below, where a back stairway afforded egress
to the lower regions where his more active interests lay.
Yes, the quietude was just now quite depressing. Sitting by an open
window, Baron looked out upon the sombre vista of back street,
which was uninviting at best, but which now presented a doubly
depressing aspect in the monotonously falling rain.
An intercepted picture of a small park was visible several blocks
away. The Lutheran church, whose bell was forever tinkling a
message of another time and place, was in sight, and so was the
shoulder of a brewery.
Closer at hand men and women were hurrying in various directions,
seeking escape from the rain. They had finished their day’s work and
were now going home to enjoy their well-earned bread and meat and
rest. Over there where the wind currents of two streets met two small
boys stood beneath a dilapidated umbrella and permitted a torrent of
muddy water in the gutter to run over their bare feet. A beer-driver,
partly sheltered under the hood of his dray, drove rumblingly over the
cobblestones toward the near-by brewery. On the ends of passing
street-cars home-going crowds were trying to escape the falling rain.
All this constituted a back-street picture which none of the Barons
observed as a rule. It was the habit of the family to confine their
outlook to the front view. But just now Baron was experiencing a
frame of mind which made the humble side of life significant and
even fascinating.
Still, he was glad to have his solitude invaded when, some time later,
he felt a light touch on his shoulder. Unheard and unobserved,
Bonnie May had stolen into the room. She had “caught” him in a
brown study.
“Don’t you think you’ve been studying your part long enough?” she
asked. She was looking at him with cheerful comprehension.
“What part?” he asked.
“Well, of course I don’t know exactly, except that it would be your
part—whatever that is. That’s what people always do when they’re
alone, isn’t it? They think how certain words will sound, or how they
will do this or that. That’s studying a part, isn’t it?”
“Oh, yes—in a way.”
She pulled a chair to the window, close to him, and climbed into it.
“There’s really something funny about it,” she added with a
reminiscent manner.
“Funny?”
“I mean about people and their parts. You know, mostly people aren’t
thinking at all about how to do their own parts better. They’re
imagining themselves in some rôle way beyond them. When they
think they are ambitious they’re mostly just sore because somebody
is doing better than they are. It’s jealousy—not ambition. My
goodness, the little parts are important enough!”
Baron regarded her in silence. Then—“but don’t you think everybody
ought to want to advance?” he asked.
“Oh, well—yes; but think how a production would be if the little parts
—even the populace—were done wrong! If I had only one line, I’d
want to believe it was as important as anything in the play.”
Baron tried to apply that philosophy to his own “part,” but he had to
admit that the result was not at all satisfactory.
“Anyway,” she added, “if you do things the way your audience wants
you to do them, I’ll bet the big parts will come fast enough.”
“The audience!” echoed Baron. “I’d want a higher standard than that.
I’d want to—to play my part the way I thought it should be done. I
wouldn’t be satisfied just with pleasing the audience.”
“Oh, but that’s the wrong idea. I’ve seen people like that. They never
were what you’d call artists. Believe me, the audience is the best
judge.”
Baron, seeking for a symbol, believed there was no hope of finding it
in this. His mind wandered, and when he brought it back to the child
who sat before him she was talking of her own problem in a way
which did not touch his at all.
“I think it’s the chance of my life,” she was saying, “my being here
with you all.”
“A chance—for what?” he asked.
“Oh, to pick things up. You know I can’t always be a Little Eva. I’ll be
too old for that after a while. And then it will be handy for me to have
a little—a little class.”
“Class!” exclaimed Baron. “Class?”
He had been arguing that the one thing wrong with his way of
thinking and living was that he and his family had attached a silly
importance to the class idea, and that it had prevented him from
learning to be active and useful in ways that counted in the world in
which he had to live.
“It’s a good thing,” defended Bonnie May. “It’s needed in all the best
plays. And you can’t get it just by going to the wardrobe mistress,
either. It’s something that’s got to be in you. In order to do it right,
you’ve pretty near got to have the goods.”
She couldn’t understand why Baron had spoken with such emphasis
—with such resentment.
“Class,” mused Baron to himself. He looked intently at this child who
did not know where she had been born—who knew nothing even
about her parentage.
But she had turned to a happier memory. “You know you can’t play
the part of Little Eva very long, even when you begin quite early. And
I was just a little bit of a thing when I played it first.” She laughed
heartily. “I couldn’t even speak plain. I used to say ‘U’kle Tom’! How
they laughed at me! ‘U’kle Tom!’ It’s really a hideous word, isn’t it?
‘Uncle,’ and ‘aunt,’ too. You can see that the man who framed up
those words never thought very highly of uncles and aunts. Just
compare those words with ‘father’ and ‘mother’! Aren’t they lovely?
Father!” she spoke the word musingly. “Father!” Her body drooped
forward slightly, and her face was pitched up so that she was gazing
into space. “Beautiful words, and mother! ... mother!” Her voice had
become a yearning whisper.
Baron touched her shoulders with gentle hands. “Don’t, child!” he
implored her.
She aroused herself as from a dream. Her eyes brightened. She
looked at him searchingly. “You thought ... I believe I was, too!”
She sprang to her feet. “I really do intend to pick up a lot of things
while I am here,” she added briskly. She walked across the floor. “An
imitation of a person of class,” she said. She moved with studied
elegance. “You see,” she exclaimed, turning to him, “I can’t do it at all
right! I ought to beat that.” She returned to her starting-point. “See if I
do it any better,” she said.
Mrs. Baron appeared in the doorway, but neither Baron nor the child
saw her. Again Bonnie May crossed the room. This time she
assumed a slightly careless air, and looked airily at imaginary objects
to right and left. Her movement was slightly undulating. She turned
to Baron suddenly: “What you have to do is to be really proud,
without thinking about it. I know how it ought to be done, but it’s hard
to get the hang of it. If you don’t get it just right you’re likely to look
like a saleslady.” She discovered Mrs. Baron, who stood rather
scornfully in the doorway.
“Oh, Mrs. Baron!” she exclaimed. She was somewhat dismayed. She
thought of adopting a conciliatory course. “You could show us just
what I mean, if you would,” she said.
“I came to say that dinner is ready,” said Mrs. Baron. “Could show
you what?”
“Won’t you please come here—quite over to this end of the room?
Now please go out. We’ll come right away.”
Mrs. Baron regarded her sternly. Bonnie May flushed and her glance
became softly appealing. She took Mrs. Baron’s hand and patted it.
“I’m not being rude, really,” she declared. “It’s as if we were asking
you to settle a bet, you know.”
“I don’t understand at all.”
“Well, please don’t be angry. If you are, it will spoil everything.”
Mrs. Baron turned to her son. He was telegraphing to her an earnest
appeal, in which she read an assurance that she was not to be made
ridiculous, even from the extraordinary view-point of Bonnie May.
“Did you understand that dinner is ready?” she asked.
“Yes, mother. We’ll be right down.”
Mrs. Baron left the room.
“Look at it! Look at it!” whispered Bonnie May. Her hands were
clasped in a worshipful ecstasy. Her eyes seemed to retain the
picture after Mrs. Baron had disappeared. Then she turned with swift
intensity to Baron.
“Oh, I do hope she’ll care for me a little!” she exclaimed. “She’s so—
so legitimate!”
CHAPTER XIII
A MYSTERIOUS SEARCH BEGINS

From a sky that had been rapidly clearing, a bolt fell.


Somewhere in the city, in what mysterious spot Baron could not
surmise, a search for Bonnie May began. Like a wireless message
seeking persistently for a receiving-centre, the quest of the
unclaimed child launched itself.
The afternoon delivery of letters at the mansion had been made, and
Bonnie May met the carrier at the door.
A moment later she entered the library, where Baron sat, and laid
before him a single letter.
He examined postmark and inscription without being in the least
enlightened. With a pair of scissors he cut the end from the envelope
and drew forth the single sheet it contained.
His glance dropped to the bottom of the sheet, and then he sat up
suddenly erect, and uttered an unintelligible exclamation.
For the first time in his life he had received an anonymous
communication.
The thing had the merit of brevity:
“Do not give up the child, Bonnie May, to any one who does not
present a legal claim on her.”
A disguised handwriting. This was obvious from certain
exaggerations and a lack of symmetry.
He replaced the missive in its envelope, and then he took it out and
read it again.
The thing excited him. Who could be seeking the child, after days of
silence—even of hiding? And who could have known of his
possession of her? Again, why make a mystery of the matter?
He threw the puzzling words aside. People did not pay any attention
to anonymous communications, he reflected.
Nevertheless, he could not calm himself. He started nervously at the
sound of the telephone-bell down in the dining-room.
Responding, he heard Thornburg’s voice at the other end of the wire.
“Is this Baron? Say, can you come down to my office right away?”
The manager’s voice betrayed excitement, Baron thought. Or was he
himself in an abnormal frame of mind?
“Yes, certainly,” he replied. He added: “Anything wrong?”
“Why—no; no, I think not. I’ll tell you when you get here.”
Something was wrong, however—Baron could see it the moment he
entered the manager’s office, half an hour later.
He had to wait a little while for an audience. Thornburg was talking to
an actress—or to a woman who had the appearance of an actress.
She sat with her back toward the office door and did not turn. But
Thornburg, upon Baron’s entrance, made a very obvious effort to
bring the interview with this earlier caller to an end. He seemed
vastly uncomfortable.
“What you ought to do is to get a stock engagement somewhere,”
Thornburg was saying impatiently. “I might possibly get you in with
Abramson, out in San Francisco. He wrote me the other day about a
utility woman. I’ll look up his letter and see if there’s anything in it.
You might come back.”
He arose with decision, fairly lifting the woman to her feet by the
force of peremptory example. “About that other matter—” he moved
toward the door, clearly intimating that he wished to finish what he
had to say outside the office.
The woman followed; but in passing Baron she paused, and her
eyes rested upon him sharply. There was a suggestion of suspicion
in her manner, in her glance, and Baron had the vexing sensation of
having seen her before without being able to identify her. A furrow
appeared in his forehead. He made a determined effort to remember.
No, he couldn’t place her. She might be an actress he had seen on
the stage somewhere or other.
She and Thornburg passed out of the office and the manager closed
the door behind him. Baron could still hear their voices, now lowered
to an angry whisper. Thornburg seemed to be speaking accusingly,
but Baron could not catch the words.
Then this one sentence, in Thornburg’s voice, came sharply: “I tell
you, you’ve worked me as long as you’re going to!”
Then the manager, flushed and excited, re-entered the office and
closed the door angrily.
And in that moment Baron remembered: That was the woman who
had stood in the theatre, talking in a tense fashion with the manager,
the day he, Baron, had sat up in the balcony box with Bonnie May!
He had no time to ponder this fact, however. Thornburg turned to
him abruptly. “Have you seen the Times to-day?” he asked.
“I glanced at it. Why?”
The manager took a copy of the paper from a pigeonhole in his desk.
“Look at that,” he directed, handing the paper to Baron. It was folded
so that a somewhat obscure item was uppermost.
Baron read: “Any one having knowledge of the whereabouts of the
child calling herself Bonnie May, and professionally known by that
name, will please communicate with X Y Z, in care of the Times.”
Baron dropped the paper on the desk and turned to Thornburg
without speaking.
The manager, now strangely quiet and morose, gazed abstractedly
at the floor. “I wish,” he said at length, “I wish she was in Tophet, or
somewhere else outside my jurisdiction.”
“But how do you know it is a she?” demanded Baron, indicating the
newspaper.
“I mean Bonnie May. I don’t know anything about that
advertisement.”
For a moment Baron could only stare at the manager. He was wholly
at sea. He was beginning to feel a deep resentment. He had done
nothing that a man need apologize for. By a fair enough
interpretation it might be said that he had tried to do a good deed.
And now he was being caught in the meshes of a mystery—and
Thornburg was behaving disagreeably, unreasonably.
He leaned back in his chair and tried to assume a perfectly tranquil
manner. He was determined not to lose his head.
“This advertisement,” he said, “seems to solve the problem. The
writer of it may not care to take Bonnie May to Tophet; but at least he
—or she—seems ready enough to take her off our hands. Off my
hands, I should say. What more do you want?”
The manager scowled. “I don’t want anybody to take her off your
hands, nor my hands.”
“Why not? If they’re entitled to her——”
“I don’t believe they’re entitled to her. A child like that.... She’s worth
a lot to people who know how to handle her. Somebody who needs
her in his business is probably trying to get hold of her.”
“Oh, that doesn’t sound reasonable to me at all. Somebody has had
charge of her. Somebody brought her to the theatre. Her mother, in
all probability.” Baron tried to speak quite casually. “Possibly her
father’s somewhere about, too.”
Thornburg glared resentfully at the younger man. “If her mother was
about,” he demanded, “would she have waited all this while to
speak?”
Baron was silenced for a moment. “Well, then,” he asked at length,
“what is your sizing up of the case?”
“I think she was deserted, maybe because for the moment she was a
burden. I think some tin-horn manager is looking for her now. And
here’s another thing I know. I want her myself!”
“But you were just saying——”
“Well, then, my wife wants her. It’s the same thing. She made up her
mind, and now she won’t change it. When I went home that night
and reported that we couldn’t have her, she began to cry. She
wouldn’t leave her bed the next morning. She’s been sick ever since.
She’ll lie for hours at a time without saying anything but—‘I wish we
could have had the little girl.’ It’s nonsense, of course; but you have
to take things as you find them. The doctor says I must get her
interested in something—as if the thing were perfectly simple. If he’d
ever run a theatre he’d know what it means to get anybody
interested. Well, there....” He calmed himself suddenly and leaned
toward Baron. His next words were little more than whispered. “You
see,” he said, “I’m fond of her—of the wife. I don’t know if you could
understand how I feel. She’s all I’ve got, and there’s a good bit of the
child about her, and she hasn’t been quite well for a long time. She
needs me to think and plan for her—to understand her, as far as I
can. You interested her in this child. She wants her. And I want her to
have her.”
“That’s plain,” said Baron. He was trying not to be too much
influenced by the manager’s sudden humility, his voicing of a need.
So far as he knew, he had his own rights in the case. And above
everything else there was to be considered Bonnie May’s right. If it
seemed best for her to remain in the mansion, there, Baron resolved,
she should remain, until he was forced to release her. “That’s plain,”
he repeated. “I think it makes the case simple enough. At least it
makes it simpler. Why not communicate with these people who are
advertising? If they have any claim on her you can come to terms
with them. They ought to be glad to see her placed in a good home.
If they haven’t any claims, the sooner we know it the better.”
“I don’t intend to pay any attention to them,” declared Thornburg. He
was sullen and stubborn again.
“Well, of course it isn’t up to you,” agreed Baron mildly. “It’s I who
must do it, as of course I shall.”
“That’s precisely what I don’t want you to do. That’s why I sent for
you.”
Baron flushed. “But—” he objected.
“Do you know what’ll happen if you show your hand? I’ll tell you. A
lot of mountebanks will be pouring into your house. They’ll make it
look like a third-rate booking agency. Your people will like that!”
Baron could see the picture: the grotesque persons at his door; the
sallow tragedian with a bass voice and no mentality to speak of; the
low comedian, fat and obtuse; the ingénue with big, childish eyes
and deep lines in her face; the leading lady with a self-imposed
burden of cheap jewelry. He saw, too, the big-hearted among them,
gravely kind toward children, and with a carefully schooled yearning
for them.
He straightened up with a jerk. “Oh, that wouldn’t be necessary,” he
declared. “I could correspond with them through the agency of the
newspaper. I needn’t give them my name and address at all. I could
require proper proofs before I appeared in the matter at all
personally.”
This idea seemed to strike Thornburg as a method of escape from a
dilemma. “Why shouldn’t I have thought of that way myself?” he
exclaimed. “I can do it that way, of course. Better for me than for you.
More in my line, at least.”
“I’m inclined to think I ought to do it myself,” objected Baron. “I really
don’t see why I should leave it to you.” Something in Thornburg’s
manner had created a suspicion in his mind. There was something
too eager in the manager’s tone; there was a hint of cunning.
“If I give you my word?” said Thornburg. He was resentful, offended.
His face had flamed to the roots of his hair.
“Oh, if you give me your word,” agreed Baron lightly. “I’ve no
objection. Certainly, go ahead.” He scrutinized his stick with a long,
frowning inspection. Then he arose with decision. “I’ll leave it to you,”
he added. “Only, I want to make one condition.”
“Oh—a condition! Well, what?”
“You’ll not take offense, Thornburg. You see, I have certain
scruples.” His mind had gone back over several episodes, and his
analysis of them pointed unyieldingly to one plain duty. “I want to ask
you just one question, and you’re to answer it in just a word: Yes, or
No.”
“Well, what’s the question?”
Baron looked steadily into the other’s eyes.
“The woman who was here in your office when I came in; who stood
with you in the theatre that day I took Bonnie May home——”
“Well?”
“Is she the—the former Mrs. Thornburg? Is she the mother of Bonnie
May?”
And Thornburg’s answer came resolutely, promptly, in the tone of a
man who tells the truth:
“No!”
CHAPTER XIV
MR. ADDIS RECEIVES SUPPORT

Unconscious that destiny had its eye upon her, Bonnie May found
increasing comfort and contentment in her new home.
As a result of the delighted labors of Flora, her wardrobe had
become more complete than it had ever been before. She developed
such pride in the possession of many garments that Flora forgot her
own needs and gave disproportionately of her time and means to the
“outfitting” of the guest whose needs were so urgent.
As if for her special entertainment, unusual things happened.
For example, Mr. Addis called again. And a call from Mr. Addis
became, in Bonnie May’s drama-loving mind, the most delicious form
of intrigue. Mrs. Baron became indignant at the very mention of Mr.
Addis’s name. Flora became quietly wistful.
Kneeling on a low Brussels hassock at the front window of the upper
floor one night, Bonnie May saw the figure of a man extricate itself
from the passing current of humanity and make resolutely for the
Baron door.
She swiftly placed her finger on her lip and reflected. “Mr. Addis!” she
exclaimed in a whisper.
She made a supreme effort to leave the room without appearing to
have any definite purpose. Once out of sight in the hall, however,
she rushed down the stairs, just in time to open the door before the
bell was rung. She was in an elated state. She had the lower floor to
herself, save for Mrs. Shepard, who would be sure not to interrupt.
“Oh! Mr. Addis!” she whispered eagerly. She promptly ushered him
into the drawing-room and quietly closed the door with an effect of
being absent-minded, rather than designing. “Please sit down,” she
said. She had the light burning immediately.
She drew a chair forward and stood beside it a moment, and under
her inspection Mr. Addis’s cheeks took on even a deeper rosiness
and his brown eyes twinkled.
“How is—my confederate?” he asked.
She was delighted. “That’s it,” she said. “That’s what I want to be.
Your confederate. May I?”
“You may,” he said with emphasis.
She had sat down. “You know,” she confided, “I’m strong for what
you call heart interest. If you haven’t got anything but manners in
your show you soon find that people are patronizing the burlesque
houses. Don’t you think I’m right?”
Mr. Addis did not make a very pertinent response to this. “You’re a
queer little customer,” he said.
“That’s what I call favorable criticism put into plain words. I thank
you.” She added: “I want to be friends with you if you’ll let me
because I think we can’t have the right kind of heart interest around
here unless you—unless you take a more prominent part.”
Mr. Addis nodded. “That’s my idea, too. That’s why I called. If you’ll
tell Mrs. Baron I’m here, I’ll see if I can’t get her to agree with us.”
Bonnie May did not stir. “Please not just yet,” she begged. “Couldn’t
we talk things over first? If I could find out what’s wrong....” She
looked at him with pretty embarrassment.
“What, for instance, would you like to know?”
She pulled herself farther back into her chair and reflected a
moment. “Would you mind,” she asked, “telling me how you got
acquainted with Miss Flora?”
“Not at all. She’s been coming to my store—to order things—ever
since she was a little girl.”
“Oh! your store. Well, go on.”
“And occasionally I’ve dropped into the church she goes to. You
know who I am, I suppose?”
She beamed upon him. “I may not have all the details. Suppose you
make a complete confession.”
He shot a dubious glance at her; then he smiled. Bonnie May
thought his teeth were quite wonderful. “I’m the head of the Addis
Stores Company.”
Bonnie May looked slightly dismayed.
“A business man,” added Mr. Addis firmly. “I’ve admired Miss Flora a
very long time. I had chances just to be nice and polite to her. I
haven’t taken any pains to hide from her, for a year or so——”
“I understand,” Bonnie May finished for him.
“Well, then. But the trouble is that Mrs. Baron——”
“She can only see you with a pencil behind your ear,” supplemented
Bonnie May.
Mr. Addis laughed. “Now you have it!” he agreed.
Bonnie May pondered. “You know you’re not a regular-looking
Romeo,” she conceded.
“I know that very well. But at the same time——”
She gave him time to finish; then, as he seemed to lack words, she
came to his aid again: “If you undertook to pay a lady’s travelling
expenses, it would take a pretty smooth Iago to make you do
anything nasty.”
“That’s it!” agreed Mr. Addis with emphasis.
“Have you tried the—the little, unimportant things?”
“As for example?”
“Well, just as a suggestion: you know you weren’t carrying a stick
when you came in to-night.”
“Oh, that sort of thing. You see, that’s not in my line at all. I wouldn’t
know how to carry a stick, or where to put it. I don’t see any use in
’em except to beat off dogs, maybe—and all the dogs like me!”

You might also like