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

AltStyle によって変換されたページ (->オリジナル) /