A program has one configuration, one log, one registry of plugins, and every part of the program must see the same one. A Singleton creates that one instance and shares it.
The classic form is a class that refuses a second instance. Before writing one, ask whether the language solves the problem for you, the question When a Pattern Dissolves poses for every pattern. For Singleton, the language has an answer.
Python imports each
module once and caches it in sys.modules. Every
import after the first produces the same module
object. A module is a singleton. Whatever it defines at module
level exists once per interpreter, and every importer shares
it.
One interpreter, not one machine. A
process pool or an InterpreterPoolExecutor
gives each worker its own sys.modules, so each
worker builds its own copy. A write in one copy leaves the other
copies unchanged. A singleton is single within the interpreter
that holds it, and every form in this chapter, the module
included, has that limit.
Put the state in a module:
# config.py
print("config body runs")
settings: dict[str, str] = {}# module_singleton.py
import sys
import config # [1]
import config as again # [2]
#: config body runs
print(config is again is sys.modules["config"])
#: TrueTwo imports of config, but
config body runs prints once. The first import of
config ([1]) creates a new module
object and stores it in sys.modules under the name
config. Then Python runs config.py top to bottom,
defining each module-level name in that module object. The
second import ([2]) finds the entry and runs
nothing, so the body runs once and builds one
settings dict. The printed True shows
that both names and the sys.modules entry are one
object. The singleton here is not a rule a class enforces, but a
lookup the import system performs.
Every import of settings, from anywhere, binds
the importer’s name to that same dict. Mutating
that dict through one import is visible through
every other:
The write goes through the name settings, and
the read through config.settings finds it, because
both names refer to one dict.
No class, no ceremony. For most singleton needs, a module solves the problem.
The three listings come down to three steps through
sys.modules. A fourth step shows the mistake that
undoes the sharing:
Steps 3 and 4 look alike in code but differ in where the
arrow points. A mutation follows the name’s arrow into the dict
that config holds, so every importer sees the
change. A rebinding moves the arrow to a new dict and leaves the
module’s dict as it was.
from config import settings gives your module
its own name for the same dict object named by
config.settings. Mutating through your name,
settings["theme"] = "dark", changes that shared
object, so every module sees it. But settings = {}
in your module rebinds your module’s name. Your module and
config silently diverge.
config.settings still holds the old dict, while
your module’s name now refers to a new, unshared dict.
To replace the whole value, go through the module:
import config, then
config.settings = {...}. Code that reads
config.settings then gets the new dict. In a module
that ran from config import settings earlier, that
module’s settings still refers to the old dict.
When such modules exist, replace the contents in place with
settings.clear() and
settings.update(). Mutate through any name. Rebind
only through the module.
Sharing also depends on the name. sys.modules
uses the module name as its key, and the file you launch runs
under the name __main__. If that file is config.py, a later
import config finds no cached entry, runs the body
again, and builds a second module object with its own
settings. Keep singleton state in a module you
import, not in the script you run.
A module’s state is a set of loose names. When the shared state has fields and methods that belong together, or other code needs a type to name in an annotation, you need a class. Every construction should then return the same object.
The simplest approach hides
construction behind a cached factory, which applies
functools.cache to a constructor function.
A constructor function is an ordinary function that builds and
returns an instance of a class, and it stands in for a direct
call to the class constructor.
functools.cache
memoizes a function. The first call with a given set of
arguments runs the function and stores the result. Every repeat
call with those arguments returns the stored result. A
constructor function with no parameters has only one possible
call, so caching it constructs the instance once and returns
that same object on every later call:
# singleton_cached_factory.py
from dataclasses import dataclass, field
from functools import cache
@dataclass
class Settings:
data: dict[str, str] = field(default_factory=dict)
@cache
def settings() -> Settings:
return Settings()
a = settings()
b = settings()
print(a is b)
#: True
a.data["theme"] = "dark"
print(b)
#: Settings(data={'theme': 'dark'})A constructor function with a parameter can return more than
one instance. functools.cache keys its cache on the
arguments, so each distinct set of arguments gets its own entry
and its own instance:
# singleton_cached_factory_footgun.py
from dataclasses import dataclass, field
from functools import cache
@dataclass
class Settings:
data: dict[str, str] = field(default_factory=dict)
@cache
def settings(env: str = "prod") -> Settings:
return Settings()
print(len({id(settings()), id(settings("prod")),
id(settings(env="prod"))}))
#: 3One parameter turns “one singleton” into one singleton per argument value. A default does not help. The cache keys on the arguments as the call writes them, before Python fills in any default. The three calls in the listing therefore build three objects for one environment. Keep the constructor function’s signature empty, or accept that you built a cache, not a singleton.
A caller can write Settings() and get a second
instance. Naming the class _Settings marks it
internal and keeps it out of from module import *.
Python enforces nothing more.
A second underscore adds no protection. The compiler mangles
names only inside a class body, so at module level
__Settings keeps its name as written, as reachable
as any other. The second underscore has one effect: it breaks a
reference written inside a class body. There the compiler
rewrites m.__Settings into a lookup for
m._TheClass__Settings. That lookup fails.
The cached-factory listings name the class
Settings, with no underscore, because the name is
public. settings() returns a Settings,
so the class appears in the module’s public signature. A caller
who annotates the result must write that name. A type outsiders
must name is public, whatever its first character.
_Settings fits a type that stays inside the
module.
Two stronger-looking moves fail the same way. Deleting the
name after building the instance leaves the class reachable.
type(settings()) returns the class. Defining the
class inside settings() puts its name in the
function’s locals, and @cache runs that body once.
type(settings()) still recovers the class.
Nesting also breaks the return
annotation. def settings() -> Settings still
parses and runs, because an annotation evaluates only when
something reads it. A clean run therefore proves nothing about
the name. Whatever reads the annotation searches the scope
containing the function, while the class lives in the function’s
own locals. A type checker reports an unresolved reference, and
inspect.get_annotations() raises a
NameError. The signature must name something
reachable, so a nested class forces a choice between dropping
the annotation and defining a separate Protocol to
name in its place.
Privacy in Python is advice, not enforcement. An underscore
marks a name as internal. Python lets any caller use it. Rethinking
Objects makes the same case about hidden data. The reachable
class is also useful when a test needs a fresh
Settings, built outside the cache.
A singleton holds shared state, and shared state leaks
between tests. The cached factory offers a reset the classic
forms lack. settings.cache_clear() discards the
instance, so each test can start fresh.
Every lazy singleton
builds its object on the first call, so it has a first-call race
under threads. Concurrent first calls can each run the
constructor. Each caller can end up holding a different object.
The cache keeps one of those objects. With a constructor slow
enough to widen that race, eight threads calling
settings() at once usually run the constructor
eight times and return eight different objects. When threads can
arrive before the singleton exists, create it eagerly
instead. Call settings() once at import time, or
use the module form, which the import system builds
once.
A lock
is the other fix for that race. A threading.Lock
around the constructor function’s body changes nothing, because
every thread misses the cache before reaching the lock. The
threads serialize, but each still builds an object. The cache
keeps whichever finished last. The check must run inside the
lock, as singleton_locked_settings.py
shows.
The first-call race is easy to see with a wide enough window.
The four race listings in this chapter share a slow
Settings and a distinct_objects()
helper. The helper calls a factory from eight threads at once
and counts the distinct objects they get back:
# race_settings.py
import time
from collections.abc import Callable
from concurrent.futures import ThreadPoolExecutor
from dataclasses import dataclass, field
@dataclass
class Settings:
data: dict[str, str] = field(default_factory=dict)
def __post_init__(self) -> None:
time.sleep(0.05) # Widen the first-call window
def distinct_objects(factory: Callable[[], object]) -> int:
with ThreadPoolExecutor(max_workers=8) as pool:
futures = [pool.submit(factory) for _ in range(8)]
return len({id(f.result()) for f in futures})The sleep stands in for a constructor that does real work, such as opening a file or a connection. Without the sleep, the cached version below returned one object in each of twenty trials. A race that testing misses is the more dangerous case. A window too narrow to reproduce is still a window.
# singleton_cached_race.py
from functools import cache
from race_settings import Settings, distinct_objects
@cache
def settings() -> Settings:
return Settings()
print(distinct_objects(settings) > 1)
#: TrueEvery thread checks the cache before any of them has filled it, so each runs the constructor and returns a different object to its caller. The object from the last thread to finish stays in the cache. The other seven stay with the callers that received them.
The listing prints a comparison instead of the count because the count depends on timing. The count is eight when every thread misses the cache, and the sleep makes that result likely.
The fix puts the check inside a lock. @cache
runs its check inside its own wrapper, where your code cannot
put a lock around it. So the locked version drops
@cache and writes the check by hand:
# singleton_locked_settings.py
import threading
from typing import Final
from race_settings import Settings, distinct_objects
_lock: Final[threading.Lock] = threading.Lock()
_instance: Settings | None = None
def settings() -> Settings:
global _instance
with _lock:
if _instance is None:
_instance = Settings()
return _instance
print(distinct_objects(settings))
#: 1One thread finds _instance empty and builds it.
The rest wait on the lock, and each finds _instance
filled. Under the same eight-thread race, the cached version
produces more than one object, usually eight. The locked version
produces one, as the printed count confirms.
settings() declares
global for _instance and leaves
_lock undeclared. The mutate-versus-rebind
distinction reappears here, from inside a function.
global governs
rebinding, not use. with _lock: reads the name,
although acquiring and releasing changes that lock’s state, from
unlocked to locked and back. Changing an object is not rebinding
a name. _instance differs because the function
assigns to it. Python decides at compile time that a name a
function assigns anywhere is local everywhere in that function.
Without the global declaration,
if _instance is None reads an unassigned local and
raises an UnboundLocalError. Mutate through any
name. Declare only what you rebind.
Every call to the locked settings() acquires the
lock, including the thousands that arrive long after the object
exists.
The classic workaround is double-checked locking:
test _instance before taking the lock, take it when
the test finds the object missing, then test again inside:
# singleton_double_checked.py
import threading
from typing import Final
from race_settings import Settings, distinct_objects
_lock: Final[threading.Lock] = threading.Lock()
_instance: Settings | None = None
def settings() -> Settings:
global _instance
if _instance is None: # [1]
with _lock:
if _instance is None: # [2]
_instance = Settings()
return _instance
print(distinct_objects(settings))
#: 1The inner test ([2]) is the check inside the
lock from singleton_locked_settings.py.
The outer test ([1]) exists to skip the lock once
the object is there.
Double-checked locking works, but it depends on two details.
If you drop the inner test, every thread that passed the outer
test before the first assignment builds its own object, one
after another. And the assignment to _instance must
be the last step of construction. The outer test runs outside
the lock, so a thread can read _instance while
another thread is still inside the with block. In a
version that assigns _instance = Settings() and
then fills in data, that reader’s
settings() returns a half-built object. Skipping
one lock acquisition per call rarely justifies two details that
must both stay right.
Eager creation is a better answer when you can build the object at import time:
# singleton_eager_factory.py
from functools import cache
from race_settings import Settings, distinct_objects
@cache
def settings() -> Settings:
return Settings()
settings() # Build it before any thread can race for it
print(distinct_objects(settings))
#: 1Apart from the line it prints, the listing is singleton_cached_race.py
plus the priming call. The eight threads now get back one
object. The priming call is safe for the same reason the module
form is. The import system runs a module body once, so the
object exists before any thread can ask for it. The race needs
laziness, and this listing gives it up on purpose.
If you need the class to hand back one instance from its own
constructor, override __new__(), as singleton_class_variable.py
does.
Modules and cached factories, primed at import time if threads are in play, should cover your singleton needs.
GoF Design Patterns
writes its examples in C++ and Smalltalk, and it builds the
singleton with more apparatus. Its class blocks direct
construction and hands out the sole instance through a class
operation, Instance(), which builds the object on
the first call. The cached factory’s settings() is
that operation written as a function. Python cannot block
construction, so the class-based forms here keep the
constructor public and route every construction to the same
shared state. Each does more work than a module or a cached
factory.
The first form wraps a single instance of a private nested class. The second form keeps the instance in a class variable. Alex Martelli’s Borg replaces the one object with many objects that share one set of state. The last form is a class decorator.
The classic approach is lazy. It
builds the inner object on the first call, so it needs the
None sentinel and the if guard.
# singleton_pattern.py
from dataclasses import dataclass, field
from typing import Any, ClassVar
class OnlyOne:
@dataclass
class __OnlyOne:
val: list[str] = field(default_factory=list)
instance: ClassVar[__OnlyOne | None] = None
def __init__(self, arg: str) -> None:
if OnlyOne.instance is None:
OnlyOne.instance = OnlyOne.__OnlyOne()
OnlyOne.instance.val.append(arg)
def __getattr__(self, name: str) -> Any:
return getattr(self.instance, name)
x = OnlyOne("sausage")
y = OnlyOne("eggs")
z = OnlyOne("spam")
print(x.val)
#: ['sausage', 'eggs', 'spam']
# Distinct wrappers (x is not y), one shared inner instance:
print(x is y, x.instance is y.instance is z.instance)
#: False TrueBecause the inner class’s name starts with a double
underscore, the compiler mangles it to
_OnlyOne__OnlyOne wherever it appears inside
OnlyOne’s body. Code outside the class that writes
OnlyOne.__OnlyOne asks for __OnlyOne,
while the class stores the attribute as
_OnlyOne__OnlyOne. That lookup fails at runtime
with an AttributeError, not at type-checking
time.
The outer class controls creation through its constructor.
The first construction of an OnlyOne initializes
instance. Every later construction reuses that
inner object. Each construction, the first included, appends its
argument to that object’s shared list.
__getattr__()
delegates access. Python calls it only when ordinary attribute
lookup fails, so a name the wrapper does not have, such as
val, falls through to the inner object. The
distinct OnlyOne instances all proxy to the same
__OnlyOne object.
The proxying covers reads. An
assignment such as x.val = [] goes into the
wrapper’s own __dict__. The shared list stays as it
was, and later reads of x.val find the wrapper’s
copy. Forwarding
Writes adds the __setattr__() that forwards
assignments.
__getattr__() returns Any, and that
Any stays. instance is one declared
field, so its annotation can say __OnlyOne | None.
Python calls __getattr__() for every name it fails
to find on the wrapper, an open set of names. The method’s
return type is whatever the inner object holds under each name,
so Any is the one annotation that fits. Delegation
gives up static knowledge to forward every name, as it does
throughout Surrogate.
When the inner object needs
nothing from that first call, you can create it eagerly in the
class body instead,
instance: ClassVar[__OnlyOne] = __OnlyOne(). Eager
creation removes the sentinel, the guard, and the first-call
race that the cached factory has under threads. The class then
builds the object whether or not anything uses it (see exercise
1). (The bare __OnlyOne() works because the nested
class exists at that point in the body. The qualified
OnlyOne.__OnlyOne() fails, since the name
OnlyOne stays unbound until its own class body
finishes running.)
Either way, OnlyOne is a lot of code for what a
module does on its own.
The nested private class is optional.
SingletonClassVar keeps the single instance in a
class variable instead. __new__() is the method
that creates an instance. Here it builds the single instance on
the first construction and returns that instance from every
construction:
# singleton_class_variable.py
from typing import ClassVar
class SingletonClassVar:
val: list[str]
__instance: ClassVar[SingletonClassVar | None] = None
def __new__(cls, arg: str) -> SingletonClassVar:
if SingletonClassVar.__instance is None:
SingletonClassVar.__instance = (
object.__new__(cls))
SingletonClassVar.__instance.val = []
SingletonClassVar.__instance.val.append(arg)
return SingletonClassVar.__instance
x = SingletonClassVar("sausage")
y = SingletonClassVar("eggs")
z = SingletonClassVar("spam")
print(x.val, x is y is z, isinstance(x, SingletonClassVar))
#: ['sausage', 'eggs', 'spam'] True Trueobject.__new__(cls)
builds a real SingletonClassVar, so
isinstance() reports True for the
instance every construction hands back. Python uses whatever
object __new__() returns as the result of the
construction. The type of that object determines whether
__init__() runs. When __new__()
returns an instance of the class under construction, Python runs
__init__() on it. A __new__() that
returns some other object skips __init__() and
fails isinstance() as well. A singleton
__new__() returns an instance of the class on every
construction, so Python runs __init__() on the
shared instance after every construction (see exercise
7). SingletonClassVar defines no
__init__(), so __new__() does all the
work.
Alex Martelli
observes that what you usually want is not one object but
one shared set of state. People can create as many objects as
they like, as long as they all share the same data. He called
that design the Borg.1 A Borg points every
instance’s __dict__ at the same storage:
The previous singleton designs stand alone, but you reuse Borg through inheritance:
# singleton_borg.py
from typing import Any, ClassVar
class Borg:
_shared_state: ClassVar[dict[str, Any]] = {}
def __init__(self) -> None:
self.__dict__ = self._shared_state
class Singleton(Borg):
def __init__(self, arg: str) -> None:
super().__init__()
self.val = argsingleton_borg_demo.py
constructs three Singleton objects:
# singleton_borg_demo.py
from singleton_borg import Singleton
x = Singleton("sausage")
y = Singleton("eggs")
z = Singleton("spam")
# Last write wins: distinct objects, one shared __dict__:
print(x.val, x is y, x.__dict__ is y.__dict__ is z.__dict__)
#: spam False TrueSingleton writes its
__init__() by hand, and it cannot be a
@dataclass. The sharing depends on
super().__init__() rebinding
self.__dict__ to _shared_state. A
dataclass generates its own __init__(), which
assigns the fields and skips
the base __init__(), so each instance keeps its
own __dict__. The dataclass version still runs, but
the class has quietly stopped being a Borg. A
__post_init__() that does the rebinding fails
differently. It runs after __init__() has assigned
the fields, so the rebinding discards them, and reading
val raises an AttributeError. Silently
losing the sharing is worse than failing outright. The
hand-written __init__() keeps the sharing.
The sharing also spans subclasses. _shared_state
is one dict on Borg, so every instance of every
subclass shares it. A second subclass alongside
Singleton writes into the same dict, so
constructing one of each leaves both objects reading the value
set last. A subclass that needs storage of its own declares it:
class Singleton(Borg): _shared_state: ClassVar[dict[str, Any]] = {}.
The lookup through self finds the subclass’s dict
first. Martelli wrote self._shared_state instead of
Borg._shared_state to allow that override.
Borg has no cache_clear(), so whatever
one test leaves in _shared_state stays there for
the next. A pytest fixture that clears the dict before each test
gives every test empty shared state.
test_borg_shares_state_but_not_identity confirms
that the objects differ but share one set of state.
test_leaves_an_attribute_behind writes an attribute
into the shared dict, and
test_fixture_clears_shared_state confirms that the
next test finds it gone:
# test_singleton_borg.py
import pytest
from singleton_borg import Borg, Singleton
@pytest.fixture(autouse=True)
def reset_shared_state() -> None:
Borg._shared_state.clear()
def test_borg_shares_state_but_not_identity() -> None:
x = Singleton("first")
y = Singleton("second")
assert x is not y # Distinct objects
assert x.__dict__ is y.__dict__
assert x.val == "second"
def test_leaves_an_attribute_behind() -> None:
setattr(Singleton("first"), "extra", "leftover")
def test_fixture_clears_shared_state() -> None:
y = Singleton("second")
assert not hasattr(y, "extra") # Reset ranA class decorator can wrap a class so that calling it returns a cached instance:
# singleton_class.py
from typing import Any
class singleton:
def __init__(self, wrapped: type) -> None:
self.wrapped = wrapped
self.instance: Any = None
def __call__(self, *args: Any, **kwargs: Any) -> Any:
print(f"singleton.__call__({args}, {kwargs})")
name = self.wrapped.__name__
if self.instance is None:
print(f"constructing {name}")
self.instance = self.wrapped(*args, **kwargs)
else:
print(f"cached {name}: arguments discarded")
return self.instance
@singleton
class Registry:
def __init__(self, name: str, *,
limit: int = 10) -> None:
print(f"Registry.__init__({name}, {limit})")
self.name = name
self.limit = limit
self.items: list[str] = []@singleton on Registry runs
Registry = singleton(Registry). The name
Registry now refers to a singleton
object that holds the class, not to the class.
Why does __call__()
intercept the constructor for a Registry? To
evaluate obj(...), Python looks
up __call__() on the type of
obj. For an ordinary class C,
type(C) is type, so the parentheses
run type.__call__(), the machinery that invokes
__new__() and then __init__(). After
decoration, type(Registry) is
singleton, so the same parentheses run
singleton.__call__() instead. The wrapped class’s
constructor runs only when that method calls it.
__call__() forwards *args and
**kwargs to the constructor of the wrapped class,
so Registry("primary", limit=3) reaches the real
constructor unchanged.
# singleton_class_demo.py
from singleton_class import Registry
first = Registry("primary", limit=3)
#: singleton.__call__(('primary',), {'limit': 3})
#: constructing Registry
#: Registry.__init__(primary, 3)
first.items.append("spam")
first.items.append("eggs")
second = Registry("secondary", limit=99)
#: singleton.__call__(('secondary',), {'limit': 99})
#: cached Registry: arguments discarded
print(first is second, second.name,
second.limit, second.items)
#: True primary 3 ['spam', 'eggs']Only the first call constructs a Registry. Every
later constructor call returns the cached instance, so
Registry("secondary", limit=99) creates no new
object. Its arguments appear once in the trace, on the
singleton.__call__() line, and
__call__() discards them. A caller who believes
those arguments took effect holds an object configured by
someone else.
isinstance() requires
a class, a tuple of classes, or a union as its second argument,
and Registry now names a singleton
object. So isinstance(first, Registry) raises a
TypeError, and so does
class Sub(Registry):
# test_singleton_class.py
import pytest
from singleton_class import Registry
def test_isinstance_on_the_decorated_name_raises() -> None:
with pytest.raises(TypeError,
match="arg 2 must be a type"):
isinstance(Registry("primary"), Registry) # type: ignore
def test_subclassing_the_decorated_name_raises() -> None:
with pytest.raises(TypeError,
match="takes 2 positional"):
class Sub(Registry): # type: ignore
passty and Pyright reject Sub
statically. Its base has type singleton, not a
class. Under mypy, which ignores a class decorator’s return
type, Registry is still a class, so
Sub passes.
At runtime the class
statement raises a TypeError.
singleton.__init__() takes two positional arguments
and receives four. A class statement hands the name, bases, and
namespace to its metaclass,
and Python takes that metaclass from the type of the base, which
is singleton. Nothing in
class Sub(Registry) mentions
singleton, so the error names a class that does not
appear in the failing line. The class decorator causes that
confusion.
The decorator weakens static
checking as well. Under ty and Pyright,
Registry("primary", limit=3) is a call to
singleton.__call__(self, *args: Any, **kwargs: Any) -> Any.
A wrong argument type passes the check, and so does a misspelled
attribute on the result. Under mypy the name is still the class,
so mypy catches both. singleton_class_variable.py
keeps the name pointing at a real class, and that is the reason
to prefer it.
A metaclass can also intercept construction. Metaprogramming
shows that singleton. Its metaclass overrides
__call__(). That override skips
__new__() and __init__() on every
later construction, so only the first call’s arguments reach the
constructor. In a class that overrides __new__()
instead, as singleton_class_variable.py
does, __new__() still runs on every call. That
listing’s __new__() sets val = [] on
the first call and runs val.append(arg) on every
call, so each later argument joins the shared list, where the
metaclass form would discard it.
Metaprogramming
also covers __init_subclass__() and
__set_name__(), the simpler methods that replace
most metaclasses. A singleton needs none of this machinery,
since a module or a cached factory gives you one instance and
leaves construction alone.
Use the lightest tool that fits:
@cache), or override
__new__() as singleton_class_variable.py
does. Both create the instance on the first call, so under
threads build it once at import time or use the module
form.isinstance() check, or
subclassing. A module shares that state with every importer and
needs no class, so shared data alone is no reason to use
Borg.The elaborate GoF Design Patterns singleton is largely a workaround for languages where a module is not a first-class, single-instance namespace. In Python, a module is that single instance, so most of that ceremony is unnecessary.
Try each exercise before opening its solution.
singleton_pattern.py waits
for the first construction to build its inner object. Modify it
to use eager creation, creating the inner instance in the class
body, and remove the sentinel and the guard. What does the
change give up, and which failure from Tests, Threads, and Locks
can no longer occur?singleton_cached_factory.py
as a starting point, create a factory that manages a pool
holding a set number of objects (say, database connections) and
hands them out, rather than a single instance.shared_config.py, replace
the mutation with a rebinding,
settings = {"theme": "dark"}. Predict both printed
values before running it, and explain the difference using the
mutate-versus-rebind
distinction.threading.Lock inside
settings() in singleton_cached_race.py,
wrapping only the body of the constructor function, and run it.
Explain why the object count does not drop to one, then fix it
without a lock.singleton_borg.py a second
Borg subclass and construct one of each. Explain
the value you get back, and change the code so the two
subclasses keep separate shared state.singleton_class_variable.py,
remove the two lines of __new__() that use
val. Add an __init__(self, arg: str)
that prints arg and sets
self.val = [arg]. Predict what x.val
holds after the three constructions, then run it. Explain the
result using what __new__() returns.