Emulating Final classes in Python
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Tue Jan 17 02:32:53 EST 2017
On Tuesday 17 January 2017 18:05, Steven D'Aprano wrote:
> I wish to emulate a "final" class using Python, similar to bool:
[...]
> Any hints?
I may have a solution: here's a singleton (so more like None than bools) where
instantiating the class returns the singleton, and subclassing the class fails:
class DoneMeta(type):
_final = None
def __new__(meta, name, bases, ns):
if meta._final is None:
meta._final = cls = super().__new__(meta, name, bases, ns)
return cls
elif meta._final in bases: # Not sure this check is needed.
raise TypeError('base class is final and cannot be subclassed')
class DoneType(metaclass=DoneMeta):
__slots__ = ()
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = inst = super().__new__(cls)
return inst
return cls._instance
def __repr__(self):
return '<DONE>'
DONE = DoneType()
del DoneType, DoneMeta
assert type(DONE)() is DONE
Thoughts? Any improvements or criticism? (Apart from "don't do it" :-)
Of course this is Python, and so we can actually dig under the hood and make a
new instance if we really try:
py> x = object.__new__(type(DONE))
py> x
<DONE>
py> x is DONE
False
and similarly there are probably ways to bypass the anti-subclassing code. But
the way I see it, if you're doing that, you either know what you're doing in
which case good on you, or you don't, in which case you deserve whatever
happens to you :-)
--
Steven
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." - Jon Ronson
More information about the Python-list
mailing list