[Python-ideas] The prohibition overrides the class method

Andrew Barnert abarnert at yahoo.com
Mon Nov 16 12:07:43 EST 2015


On Nov 16, 2015, at 07:03, Иван Спиненко <spinenkoia at gmail.com> wrote:
> 
> Hello, I want to apologize for my English.
> I propose to make an analogue of the final specifier in C ++. In class abc.ABCMeta has decorator abstractmethod, you can add decorator finalmethod.

Since the C++ standard is (mostly) written based on public proposals on open-std.org, presumably there's some discussion of the motivation behind adding this feature to C++11. It would be worth knowing what that motivation is, to see whether it applies to Python. For example, if it was proposed just to provide optimization opportunities, or to be closer to C++/CLI, then it probably isn't worth adding to Python (unless you have Python-specific use cases to offer, and it's just a coincidence that C++ and Python could use very similar features). On the other hand, if it solves a real problem with making some hierarchies easier to read, or removing opportunities for hard-to-diagnose errors, then it may be (assuming those problems have equivalents in Python).

Sometimes there are also blog posts presenting the idea to C++ users instead of the C++ committee, which often get the motivation across better (e.g., explaining how rvalue references solve the forwarding and move problems that boost ran into with the previous version of C++).

So, if you want to suggest a feature copied from C++11, it's probably worth searching for those references and providing links and summaries.

I suspect that it's primarily for optimization. In C++, by default, methods can't be overridden, so if the compiler sees spam.cook() it can just compile in a direct call to Spam::cook. But if cook() is declared virtual in either Spam or any of its superclasses, it instead has to compile an indirect call to spam->vtable[1], which also means it will usually keep Spam::vtable in L2 cache whenever a Spam object is around, and so on, which can make a big difference. So, when the compiler can prove that spam really is a Spam, and not some subtype (e.g., because the function constructed it locally, or accepted it by value), it will optimize out the virtual call. What final adds is that if cook() is declared final in Spam or any of its superclasses, the compiler can optimize out the virtual call even if the value could actually be a subtype (e.g., because the function accepted it by reference), because it would be illegal for any such subtype to have overridden the method. So, that can be a huge benefit. Obviously, none of this applies in Python. Methods are always looked up by name in the value's dict, then the class and each of its bases at runtime; there's no concept of a variable's type to start the search at, and no way to record something that can be directly called at compile time (especially since type, function, and method objects are themselves constructed at runtime).

> I have a sketch of implementation:
> def finalmethod(funcobj):
>     funcobj.__isfinalmethod__ = True
>     return funcobj
> 
> class Override(ABCMeta):
>     def __init__(cls, name, bases, namespace):
>         super(Override, cls).__init__(name, bases, namespace)
>         finals = {name
>                         for name, value in namespace.items()
>                         if getattr(value, "__isfinalmethod__", False)
>         }
> 
>         for base in bases:
>             for name in getattr(base, "__finalmethods__", set()):
>                 value = getattr(cls, name, None)
>                 if getattr(value, "__isfinalmethod__", False):
>                     finals.add(name)
>                 else:
>                     raise TypeError("function '" + str(value.__name__) + "' in class '" + str(cls.__name__) + "' is final")
>         cls.__finalmethods__ = frozenset(finals)
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151116/0c98f2c2/attachment.html>


More information about the Python-ideas mailing list