Clients should not be forced to depend upon methods that they do not use. Interfaces belong to clients, not to hierarchies.

That is to say, if a class doesn’t use a particular method or attribute, then those methods and attributes should be segregated into a class with higher specificity.

from abc import ABC, abstractmethod
 
class Sprite(ABC):
	@abstractmethod
	def update(self):
		pass
 
	@abstractmethod
	def get_keyboard_input(self, key_input):
		pass
 
class Player(Sprite):
	def update(self):
		print("updated player")
 
	def get_keboard_input(self, key_input):
		print(f"recieved {key_input}")
 
class Enemy(Sprite):
	def update(self):
		print("updated enemy")
 
	def get_keyboard_input(self, key_input):
		raise NotImplementedError("enemies don't recieve key inputs")

Because the Abstract Class defined the methods required to instantiate a Sprite, we are required to define get_keyboard_input for Enemy, even though Enemy does not actually use it. The issue, then, is that we are defining interfaces that are not actually implemented by the clients of that interface.

To solve this, separate the methods:

from abc import ABC, abstractmethod
 
class Sprite(ABC):
	@abstractmethod
	def update(self):
		pass
 
class Player(ABC):
	@abstractmethod
	def get_keyboard_input(self, key_input):
		pass
 
class Enemy(Sprite):
	def update(self):
		print("updated enemy")
		
class Character(Player, Sprite):
	def update(self):
		print("updated player")
 
	def get_keboard_input(self, key_input):
		print(f"recieved {key_input}")

NowSprite and Player are base classes that provide specific OOP interfaces with Single Responsibility Principle (SRP) each.

Another example:

# printers_isp.py
 
from abc import ABC, abstractmethod
 
class Printer(ABC):
    @abstractmethod
    def print(self, document):
        pass
 
    @abstractmethod
    def fax(self, document):
        pass
 
    @abstractmethod
    def scan(self, document):
        pass
 
class OldPrinter(Printer):
    def print(self, document):
        print(f"Printing {document} in black and white...")
 
    def fax(self, document):
        raise NotImplementedError("Fax functionality not supported")
 
    def scan(self, document):
        raise NotImplementedError("Scan functionality not supported")
 
class ModernPrinter(Printer):
    def print(self, document):
        print(f"Printing {document} in color...")
 
    def fax(self, document):
        print(f"Faxing {document}...")
 
    def scan(self, document):
        print(f"Scanning {document}...")

Should be modified to:

# printers_isp.py
 
from abc import ABC, abstractmethod
 
class Printer(ABC):
    @abstractmethod
    def print(self, document):
        pass
 
class Fax(ABC):
    @abstractmethod
    def fax(self, document):
        pass
 
class Scanner(ABC):
    @abstractmethod
    def scan(self, document):
        pass
 
class OldPrinter(Printer):
    def print(self, document):
        print(f"Printing {document} in black and white...")
 
class NewPrinter(Printer, Fax, Scanner):
    def print(self, document):
        print(f"Printing {document} in color...")
 
    def fax(self, document):
        print(f"Faxing {document}...")
 
    def scan(self, document):
        print(f"Scanning {document}...")