Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fcda0cd

Browse files
Second full Singleton read-through
1 parent 3041154 commit fcda0cd

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

gang-of-four/singleton/index.rst

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
Python programmers almost never implement the Singleton Pattern
1414
as described in the :doc:`/gang-of-four/index`,
1515
whose Singleton class forbids normal instantiation
16-
and instead offers a class method
17-
that returns the single instance.
18-
Instead, Python lets a class offer what looks like normal instantiation
19-
that actually returns a singleton instance
20-
through a custom ``__new__()`` method.
16+
and offers a class method that returns the single instance.
17+
Instead, Python lets classes define a custom ``__new__()`` method
18+
that returns a singleton instance each time the class is called.
2119
But an even more Pythonic approach,
2220
if your design forces you to offer global access to a singleton object,
2321
is to use :doc:`/python/module-globals/index` instead.
@@ -38,7 +36,7 @@ of “singleton” in Python.
3836
The Python Tutorial itself introduces newcomers to this definition
3937
when its chapter on `Data Structures
4038
<https://docs.python.org/3/tutorial/datastructures.html>`_
41-
calls a one-element tuple a “singleton”,
39+
calls a one-element tuple a “singleton”
4240
and the word continues to be used in that sense
4341
through the rest of Python’s documentation.
4442
When the `Extending and Embedding <https://docs.python.org/3/extending/extending.html#calling-python-functions-from-c>`_
@@ -59,8 +57,7 @@ of “singleton” in Python.
5957

6058
3. A “singleton” is a class instance that has been assigned a global name
6159
through :doc:`/python/module-globals/index`.
62-
For example, the official Python
63-
`Programming FAQ <https://docs.python.org/3/faq/programming.html>`_
60+
For example, the official Python Programming FAQ
6461
answers the question
6562
`“How do I share global variables across modules?”
6663
<https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across-modules>`_
@@ -113,11 +110,10 @@ But their classes were not callable:
113110
>>> type(Ellipsis)()
114111
TypeError: cannot create 'ellipsis' instances
115112

116-
But in Python 3, the classes were upgraded to use the Singleton Pattern:
113+
In Python 3, however, the classes were upgraded to use the Singleton Pattern:
117114

118115
>>> NoneType = type(None)
119-
>>> result = NoneType()
120-
>>> print(result)
116+
>>> print(NoneType())
121117
None
122118
>>> type(Ellipsis)()
123119
Ellipsis
@@ -129,7 +125,7 @@ In most Python projects these classes are never called
129125
and the benefit remains purely theoretical.
130126
When Python programmers need the ``None`` object
131127
they use :doc:`/python/module-globals/index`
132-
by simply typing its name.
128+
and simply type its name.
133129

134130
The Gang of Four’s implementation
135131
=================================
@@ -154,27 +150,27 @@ what were their options for offering singleton objects?
154150
because it did not work particularly well
155151
in early versions of the C++ language.
156152
There, global names all shared a single crowded global namespace,
157-
and elaborate naming conventions were necessary
153+
so elaborate naming conventions were necessary
158154
to prevent names from different libraries from colliding.
159155
So the Gang judged that adding both a class and its singleton instance
160156
to the global namespace was excessive.
161157
And since C++ programmers couldn’t control the order
162158
in which global objects were initialized,
163159
no global object could depend on being able to call any other,
164-
so the responsibility for initializing each global
165-
would often have fallen on client code.
160+
so the responsibility of initializing globals
161+
often fell on client code.
166162

167-
2. There was no way to override the meaning of ``new`` in C++
163+
2. There was no way to override the meaning of ``new`` in C++,
168164
so an alternative syntax was necessary
169165
if all clients were to receive the same object.
170166
It was, though, at least possible to make it a compile-time error
171-
for client code to call ``new``,
167+
for client code to call ``new``
172168
by marking the class constructor as either ``protected`` or ``private``.
173169

174170
3. So the Gang of Four pivoted to a class method
175171
that would return the class’s singleton object.
176172
Unlike a global function,
177-
a class method avoided adding yet another name to the C++ global namespace,
173+
a class method avoided adding yet another name to the global namespace,
178174
and unlike a static method,
179175
it could support subclasses that were singletons as well.
180176

@@ -277,7 +273,7 @@ because Python lacks a ``new`` keyword
277273
that forces a new object to be created.
278274
Instead, objects are created by invoking a callable,
279275
which imposes no syntactic limitation
280-
on what operation the callable performs::
276+
on what operation the callable really performs::
281277

282278
log = Logger()
283279

@@ -290,7 +286,7 @@ The Web is replete with Singleton Pattern recipes featuring ``__new__()``
290286
that each propose a more or less complicated mechanism
291287
for working around the method’s biggest quirk:
292288
the fact that ``__init__()`` always gets called on the return value,
293-
whether the object that’s been returned is new or not.
289+
whether the object that’s being returned is new or not.
294290
To make my own example simple,
295291
I will simply not define an ``__init__()`` method
296292
and thus avoid having to work around it:
@@ -367,7 +363,7 @@ it’s not as easy to dismiss the pattern when it’s built atop ``__new__()``
367363
after all, singletons were part of the reason
368364
the ``__new__()`` dunder method was introduced!
369365

370-
But the Singleton Pattern in Python always seems to have drawbacks.
366+
But the Singleton Pattern in Python does suffer from several drawbacks.
371367

372368
A first objection is that the Singleton Pattern’s implementation
373369
is difficult for many Python programmers to read.
@@ -391,8 +387,8 @@ that :doc:`/python/module-globals/index` does not.
391387
Offering a global object still leaves code
392388
free to create other instances of the class —
393389
which can be particularly helpful for tests,
394-
that otherwise wind up coupled together
395-
through the single global object they are forced to share.
390+
letting them each test a completely separate object
391+
without needing to reset a shared object back to a known good state.
396392
But the Singleton Pattern makes additional instances impossible.
397393
(Unless the caller is willing to stoop to monkey patching;
398394
or temporarily modifying ``_instance`` to subvert the logic in ``__new__()``;
@@ -405,11 +401,14 @@ would be an existing class that,
405401
because of a new requirement,
406402
will now operate best as a single instance.
407403
If it’s not possible to migrate all client code to using a global object,
408-
then using the Singeton Pattern would be a natural approach
409-
to pivoting to a singleton design while preserving the old syntax.
404+
then the Singeton Pattern would be a natural approach
405+
to pivoting to a singleton while preserving the old syntax.
410406

411407
But, otherwise, the pattern is best avoided
412-
in favor of :doc:`/python/module-globals/index`.
408+
in favor of following the advice
409+
of the `official Python FAQ
410+
<https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across-modules>`_
411+
and using the :doc:`/python/module-globals/index`.
413412

414413
.. See also
415414

0 commit comments

Comments
 (0)