No checks are done on how many arguments concrete implementations take. So there is nothing stopping your from doing this already.

Just define those methods to take whatever parameters you need to accept:

class View(metaclass=ABCMeta):
    @abstractmethod
    def set(self):
        pass

    @abstractmethod
    def get(self):
        pass


class ConcreteView1(View):
    def set(self, param1):
        # implemenation

    def get(self, param1, param2):
        # implemenation


class ConcreteView2(View):
    def set(self):
        # implemenation

    def get(self, param1, param2):
        # implemenation

Other tools, such as linters, are a different matter. They could (rightly) claim that the above code violates the Livkov Substitution Principle, because you the subclasses and parent class take different arguments. But it is not Python itself that then tells you about this.

Answer from Martijn Pieters on Stack Overflow
🌐
Reddit
reddit.com › r/python › what's the point of abstract classes if they don't enforce method signatures?
r/Python on Reddit: What's the point of abstract classes if they don't enforce method signatures?
December 18, 2016 -

I was surprised to see the Python abstract classes don't enforce anything except the override and method name. I can see why in Python enforcing parameter data-types would probably not work, but the number of parameters and parameter names ought to be enforced.

I've always thought the point of abstract classes was to ensure that any inheritor of the class would would work with existing code to run the abstract methods defined in the super class. The whole point was to enforce method signatures.

It seems to me that Python's implantation of abstract classes has very little utility. Does anyone even use them? What for?

🌐
The Teclado Blog
blog.teclado.com › python-abc-abstract-base-classes
How to Write Cleaner Python Code Using Abstract Classes
October 26, 2022 - When the subclass implements the method, it must contain all the parameters as well. The subclass' implementation can also add extra parameters if required. from abc import ABC,abstractmethod class Animal(ABC): @abstractmethod def do(self, action): # Renamed it to "do", and it has "action" parameter pass class Lion(Animal): def do(self, action, time): # It's still mandatory to implement action.
🌐
Python
docs.python.org › 3 › library › abc.html
abc — Abstract Base Classes
You can also override this method in an abstract base class: ... Check whether subclass is considered a subclass of this ABC. This means that you can customize the behavior of issubclass() further without the need to call register() on every class you want to consider a subclass of the ABC.
🌐
GitHub
github.com › python › mypy › issues › 7424
Support for variadiac arguments for inherited classes? · Issue #7424 · python/mypy
July 28, 2019 - import abc from typing import Any class Base(abc.ABC): @abc.abstractmethod def run(self, model: Any, **kwargs: int) -> None: pass class Child(Base): def run(self, model: Any, foo : int) -> None: pass ... I sued the **kwargs annotation in reference to this PEP but I realize the use case is different. I couldn't find anything in the mypy documentation about annotating this correctly. I could of course use **kwargs in the Child class and parse optional parameters from there, but I don't think that's a good solution.
Author   adewes
🌐
Reddit
reddit.com › r/learnpython › should i use *args and **kwargs with abstract method?
r/learnpython on Reddit: Should I use *args and **kwargs with abstract method?
August 28, 2025 -

I am working in research where I am using python (numpy, scikit-learn, matplotlib mostly) to solve an optimization problem. I have a parent class where most of the code is, but we want to try two different methods for part of the optimization, so I have two child classes (one for each). I am using @ abstractmethod in the parent for the function, then I want to implement in the children.

The children implementations will not have the same parameters. Should I use *args and **kwargs in the parent implementation, or does it not matter and I can just do

@abstractmethod
def func(self):
  pass

and then in the children's implementations pass whatever I need:

class Child1(Base):
  def func(self, var1, var2):
    do_stuff
🌐
Stack Exchange
softwareengineering.stackexchange.com › questions › 441707 › abstract-factory-for-methods-constructor-with-different-arguments
python - Abstract Factory for methods/constructor with different arguments - Software Engineering Stack Exchange
You can design your factories in whatever way best suits your problem. There's no abstract factory police out there. In the original Design Patterns book, they show an example where they pass one parameter that came from the factory method, and an extra parameter that came from a private field of the factory itself.
🌐
Narkive
comp.lang.python.narkive.com › 07geq6I5 › abc-with-abstractmethod-kwargs-on-base-explicit-names-on-implementation
ABC with abstractmethod: kwargs on Base, explicit names on implementation
- I know giving `b` a default value ... a distinction between positional and keyword arguments. A positional argument is identified by its position in the parameter list; a keyword argument is identified by its name....
Find elsewhere
🌐
Medium
medium.com › @aaron_imn › enforce-abstract-methods-signature-to-derived-classes-in-python-a21414943ce6
Enforce abstract methods signature to derived classes in Python | Medium
February 26, 2024 - In this story, throughout an example, I will explain how to enforce the derived class of an abstract base class in Python to follow the same parameter types and names of the abstract methods’ parameters. In the example below, an abstract base class A has been defined that has an abstractmethod called a. The classes B and C have derived from A, whereas B follows the same signature of the abstract method a, while C does not.
🌐
ActiveState
code.activestate.com › recipes › 266468-abstract-methodsclasses
Abstract methods/classes « Python recipes « ActiveState Code
With that metaclass, it is guaranteed that you will never accitentally instantiate a class with one or more abstract classes. ... Constructor of subclasses requires 2 arguments. I have created an abstract class which (besides self) has one argument on the __init__ method. Later, I've created a subclass of that abstract one, which added one more parameter to the __init__.
🌐
YouTube
youtube.com › watch
Can I Still Use an Abstract Method With Different Parameters? - YouTube
Discover how to effectively utilize abstract methods in Python when dealing with different parameters. Gain insights into best practices and structures for d...
Published   March 30, 2025
Views   0
Top answer
1 of 2
6

The very core of what you're trying to achieve goes against the core principle of polymorphism: interchangeability.

The concept of polymorphism is having the ability to write code that handles an object of type A and not having to care whether the actual object is of type A or any of its derived types (B, C, or any of their derived types recursively).
Having different signatures for different derived types breaks the ability to polymorphically treat these as indiscriminate A objects.

Essentially, polymorphism should allow you to write code that does this (I'm switching to C# because I'm more familiar with the syntax, but this point is not language-specific):

public void DoSomething(A myA)
{
    A.Foo(myValue1, myValue2, myValue3);
}

And this code should work for all of these use cases:

DoSomething(new A());
DoSomething(new B());
DoSomething(new C());

Needing to know the specific subtype being used, while the language does allow you to do so, is polymorphism abuse and indicative of bad design and something for which inheritance was not the right tool for the job.

Without repeating very common explanations found online in many guides and blog posts, look up what a Liskov Substitution Principle (LSP) violation is, and what an Open-Closed Principle (OCP) violation is. Your if isinstance(child_cls, B) is an instance of an LSP violation, and creating a chain of if is subtype checks is an OCP violation (the two principles are spiritually linked because they touch on similar topics.
This is precisely the problem you are creating by designing your derived types in a way that a consumer needs to know whether it's B or C.


The problem here is that I can't give you the answer, because I can't tell what it is that you're trying to achieve in practice. You've told me how you want to implement your code, you've not told me why, or what you're hoping to achieve.

The only thing I can say for a fact here is that what you're trying to achieve is not achievable using polymorphism, by the very core definition of what polymorphism is. You need to go back to the drawing board on this one, research OOP concepts (I suggest revisiting what polymorphism is, and looking up SOLID guidelines and what to avoid), and then use that newfound knowledge to come up with a better solution.

2 of 2
4

At first sight, your object hierarchy breaks the Liskov Substitution Principle (the "L" in SOLID), because I cannot substitute an instance of B for an instance of A due to the differing signature of foo. Rather than wrapping this up in _call_foo, just make the public API take the union of all the parameters (i.e. make _call_foo the public API) and you're good - it's perfectly valid for subclasses to not use all the parameters on some functions.

🌐
Python.org
discuss.python.org › typing
Calling abstract methods - Typing - Discussions on Python.org
January 6, 2024 - PEP 544 indicates that a type checker should generate an error if a class that explicitly derives from the protocol attempts to call a method through super() if that method is unimplemented in the protocol. class Proto(Protocol): def method(self) -> None: ... class Impl(Proto): def method(self) -> None: super().method() # Type checker error This makes sense because the method in the protocol is effectively abstract.
Top answer
1 of 3
28

What you're trying to do will just work—but it's a very bad idea.

In general, you don't want to change the signature of a method in incompatible ways when overriding. That's part of the Liskov Substitution Principle.

In Python, there are often good reasons to violate that—inheritance isn't always about subtyping.

But when you're using ABCs to define an interface, that's explicitly about subtyping. That's the sole purpose of ABC subclasses and abstractmethod decorators, so using them to mean anything else is at best highly misleading.


In more detail:

By inheriting from Agent, you are declaring that any instance of Clever_Agent can be used as if it were an Agent. That includes being able to call my_clever_agent.perceive_world(my_observation). In fact, it doesn't just include that; that's the entirely of what it means! If that call will always fail, then no Clever_Agent is an Agent, so it shouldn't claim to be.

In some languages, you occasionally need to fake your way around interface checking, so you can later type-switch and/or "dynamic-cast" back to the actual type. But in Python, that's never necessary. There's no such thing as "a list of Agents", just a list of anything-at-alls. (Unless you're using optional static type checking—but in that case, if you need to get around the static type checking, don't declare a static type just to give yourself a hurdle to get around.)


In Python, you can extend a method beyond its superclass method by adding optional parameters, and that's perfectly valid, because it's still compatible with the explicitly-declared type. For example, this would be a perfectly reasonable thing to do:

class Clever_Agent(Agent):
    def perceive_world(self, observation, prediction=None):
        print('I see %s' % observation)
        if prediction is None:
            print('I have no predictions about what will happen next')
        else:
            print('I think I am going to see %s happen next' % prediction)

Or even this might be reasonable:

class Agent(ABC):
    @abstractmethod
    def perceive_world(self, observation, prediction):
        pass

class Dumb_agent(Agent):
    def perceive_world(self, observation, prediction=None):
        print('I see %s' % observation)
        if prediction is not None:
            print('I am too dumb to make a prediction, but I tried anyway')

class Clever_Agent(Agent):
    def perceive_world(self, observation, prediction):
        print('I see %s' % observation)
        print('I think I am going to see %s happen next' % prediction)
2 of 3
0

In many ways overriding an abstract method from a parent class and adding or changing the method signature is technically not called a method override what you may be effectively be doing is method hiding. Method override always overrides a specific existing method signature in the parent class.

You may find your way around the problem by defining a variant abstract method in your parent class, and overriding it if necessary in your sub classes.

🌐
datagy
datagy.io › home › python posts › python abc: abstract base class and abstractmethod
Python abc: Abstract Base Class and abstractmethod • datagy
December 23, 2022 - This is because both subclasses have the correct name – even if their implementations differ. In the following section, you’ll learn how to add parameters to an abstractmethod and how to enforce that they exist in any subclasses. What’s great about the abstractmethod decorator is that we can even require a method to have one or more parameters.
🌐
Python
bugs.python.org › issue20897
Issue 20897: @abstractmethod does not enforce method signatures - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/65096
🌐
Grokbase
grokbase.com › t › python › python-ideas › 109qtkrzsd › abc-what-about-the-method-arguments
[Python-ideas] ABC: what about the method arguments ? - Grokbase
Split the current test suite for a concrete class that implements one of the ABCs into concrete-specific and ABC-general portions, with the abstract part parameterized by concrete class.FWIW, bzr's test suite has this facility, and bzr plugins that implement various bzr interfaces will have tests for those interfaces automatically applied. (Being a Python 2.4+ project, bzr doesn't actually use the ABCs feature, but we certainly use the concept of "interface with many implemenations".)