0
class F(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def f(self, a, b): print("F")


class FF(F):
    def f(self): print("FF")



f = FF()
f.f()

Here, I define an abstract method f with two arguments. I want to restrict subclass so that it has same arguments like superclass.

How to do that?

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
Zephyr Guo
  • 1,083
  • 1
  • 8
  • 14

2 Answers2

1

There isn't any trivial way to check that the method signatures match.

However, assuming:

  1. Your subclass only the derives from the concerned abstract class or the abstract class is the first in its mro
  2. And that the implementation of the abstract class is empty, to eliminate any possibility of unwanted results such as binding new attributes to the subclass,

You could make a super call to the abstract method passing the paramters from the subclass method. The call only serves to enforce a signature match.

class F(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def f(self, a, b): pass


class FF(F):
    def f(self, *args, **kwargs):
        super(FF, self).f(*args, **kwargs)
        ...

f = FF()
f.f()

Traceback (most recent call last):
  File "python", line 17, in <module>
  File "python", line 12, in f
TypeError: f() takes exactly 3 arguments (1 given)

Python abstract methods (unlike others) can have implementations and can be called via super; so maybe this is one use case after all.

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
0

You can use abcmeta library: https://github.com/mortymacs/abcmeta . It gives you more restrictions on derived classes.

mortymacs
  • 3,456
  • 3
  • 27
  • 53