[Python-Dev] One-line abstractmethod function?

Allen Li cyberdupo56 at gmail.com
Thu Dec 5 22:12:28 CET 2013


On Thu, Dec 05, 2013 at 10:24:11AM -0800, Guido van Rossum wrote:
> How would you get the docstrings in? It seems cramming that much on a
> single line doesn't help readability (even though I agree there is a
> fair amount of boilerplace).

I was basing my initial suggestion somewhat on collections.namedtuple,
which doesn't support docstring either.  One option would be to simply
not allow for docstrings, requiring the boilerplate method, the other
would be to add a parameter for the docstring:

make_abstractmethod(name, arglist, docstring='')

On Thu, Dec 5, 2013 at 2:22 PM, Ethan Furman <ethan at stoneleaf.us> wrote:

> On 12/05/2013 10:56 AM, Alexander Belopolsky wrote:
>
>> On Thu, Dec 5, 2013 at 1:24 PM, Guido van Rossum wrote:
>>
>>>
>>> How would you get the docstrings in? [...]
>>>
>>
>> One way to reduce the amount of boilerplate code is to make abstractmethod
>> to supply raise NotImplementedError body when none is given.  Then you can
>>  write
>>
>> class Foo:
>>      @abc.abstractmethod
>>      def do_bar(self):
>>           """perform bar"""
>>
>> The docstring will be required when skipping the body which is probably a
>> good thing.
>>
>
> How will abstractmethod know its function has no body?

I don't think this is a good idea at all, very magical behavior.  It is
not intuitive or explicit that an abstractmethod-decorated empty
function raises NotImplementedError.

On Thu, Dec 05, 2013 at 03:06:00PM -0500, Brett Cannon wrote:
> But I would be very leery of this being a default behaviour. Raising
> NotImplementedError is not necessarily what the default result should be
> for a method. If you are building a class that supports multiple
> inheritance you will be calling super().do_bar() almost blindly which, if
> you are not careful, will raise NotImplementedError and that might not be
> appropriate. Maybe returning None is more reasonable, maybe raising
> TypeError. But support a default blindly like this can promote bad
> practices.

I'm not sure what's considered best practice with super() at the moment.
super() is dangerous if you don't know what you are doing in
multi-inheritance design, so I'd consider calling super() blindly is the
problem here, not raising NotImplementedError.  I do think raising
NotImplementedError is reasonable default behavior for an
abstractmethod.  The only two alternatives are doing nothing/pass/return
None or having actual code in the method.

The former is only useful to silently ignore blind super() calling, the
latter you would define and decorate the method normally.

On Thu, Dec 05, 2013 at 08:39:05PM +0000, MRAB wrote:
> An abstract method won't have a body (I'm not counting the docstring).
> 
> If it _does_ have a body, then it's _not_ an abstract method!

It could have a body, though I would agree it's not commonly used that
way.  Maybe something like the following (though it's a poor example):

class Printer(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def print(self):
        print("Print done.")

class Foo(Printer):

    def print(self):
        print('foo')
        super().print()


More information about the Python-Dev mailing list