
Ben Finney wrote:
Péter Szabó <ptspts@gmail.com> writes:
If Python had method decorators @final (meaning: it is an error to override this method in any subclass)
What use case is there for this? It would have to be quite strong to override the Python philosophy that “we're all consenting adults here”, and that the programmer of the subclass is the one who knows best whether a method needs overriding.
Agreed - the base class author has no right to tell subclass authors that they *can't* do something. They can give hints that something shouldn't be messed with by using a leading underscore and leaving it undocumented (or advising against overriding it in the documentation). That said, if a @suggest_final decorator was paired with an @override_final decorator, I could actually see the point: one thing that can happen with undocumented private methods and attributes in a large class heirarchy is a subclass *accidentally* overriding them, which can then lead to bugs which are tricky to track down (avoiding such conflicts is actually one of the legitimate use cases for name mangling). A suggest_final/override_final decorator pair would flag accidental naming conflicts in complicated heirarchies at class definition time, while still granting the subclass author the ability to replace the nominally 'final' methods if they found it necessary.
and @override (meaning: it is an error not having this method in a superclass)
I'm not sure I understand this one, but if I'm right this is supported now with:
class FooABC(object): def frobnicate(self): raise NotImplementedError("Must be implemented in derived class")
Even better:
import abc class FooABC(): # use metaclass keyword arg in Py3k ... __metaclass__ = abc.ABCMeta ... @abc.abstractmethod ... def must_override(): ... raise NotImplemented ...
x = FooABC() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class FooABC with abstract methods must_override
class Fail(FooABC): pass ... x = Fail() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class Fail with abstract methods must_override
class Succeed(FooABC): ... def must_override(self): ... print "Overridden!" ... x = Succeed() x.must_override() Overridden!
Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------