touchPython
Friends who were older may have had this experience.Python
Although the language also supports object-oriented programming,
However, unlike purely object-oriented languages (e.g.Java
and.NET
) So strict and standardized.
As the project gradually grows in size, it becomes increasingly difficult to define and implement the behavior of objects in a clear, maintainable and scalable way.
Two powerful tools for object-oriented programming in Python introduced today:interfaceandAbstract base class。
Their English isProtocols
andABC
(Abstract Base Classes
)。
Protocols
yesPython3.8
It has just begun to be introduced, and some places have also been translated intoprotocol, I feel that it is translated intointerfaceMore familiar.
ABC
It was introduced earlier,Python3
It has been improved and optimized later, and now there is not much difference compared with abstract classes in other languages.
1. Interface (Protocols)
Python3.8
Start the interface introduced in the type moduleProtocols
The concept of , which provides a way to define an interface without explicit inheritance.
interfaceProtocols
A set of methods or properties is defined, and as long as an object implements these methods or properties, it is considered to satisfy the interface.
Here is an example to help understandProtocols
If you have experience in object-oriented programming, you can easily understand this concept.
This example comes from a recently used part of a quantitative trading system that requires a different sourceGet data, and thenanalyze, and finally the analysis results are carried out in different waysOutput。
In these three steps (get data, analyze and output),
AssumptionsGet dataThe source of the Internet (API
),document(CSV
) and database;
The analysis steps are unified; there are many assumptions of output methods, such as email, text messages, etc.
According to this description, useProtocols
The code for the acquisition data and analysis part of the constructed code is as follows:
(The output part is not in mind for the time being)
from typing import Protocol # The interface for inputting dataclass InputData(Protocol): def get_data(self) -> str: pass class APIHandler: def get_data(self) -> str: print("get_data from API") return "get data from API" class CSVHandler: def get_data(self) -> str: print("get_data from CSV") return "get data from CSV" class SqliteHandler: def get_data(self) -> str: print("get_data from SQLITE DATABASE") return "get data from SQLITE DATABASE" #Analyze datadef analysis(i: InputData): data = i.get_data() print("Start the data...")
InputData
InheritedProtocol
, which defines the function of the interfaceget_data
。
As long as it is implementedget_data
ofclass
,for exampleAPIHandler
,CSVHandler
andSqliteHandler
, can be used asInputData
type.
As can be seen from the code, we don't need to use itAPIHandler
Go to inheritInputData
, as long as it is implementedInputData
All the methods in it are OK.
This flexibility ensures the system's scalability, and we can add new data source types without modifying existing code.
Next, we test whether the above code works normally:
if __name__ == "__main__": i = APIHandler() analysis(i) print("\n") i = CSVHandler() analysis(i) print("\n") i = SqliteHandler() analysis(i) print("\n")
Running results:
$ .\protocol_abc.py
get_data from API
Start processing data...
get_data from CSV
Start processing data...
get_data from SQLITE DATABASE
Start processing data...
2. Abstract base class (ABC)
Protocol
Very flexible, but sometimes we need a more structured approach, which is the abstract base class (ABC
) is where it comes into play.
ABC
Is a tool that enforces consistent behavior by defining strict interfaces that subclasses must implement.
andProtocol
different,ABC
explicit inheritance is required, so when we want to explicitly define the hierarchy in our code,ABC
It's a better choice.
Next, implement the example in the previous sectionOutput part, each different output requires a different configuration,
For example, when outputting to email, you need to configure the account information of the email address first, when outputting to text messages, you need to configure the mobile phone information, etc.
Here we useABC
to implement the base class of output.
# The abstract base class for outputclass OutputResult(ABC): def __init__(self): : dict = {} @abstractmethod def send(self, data: str): pass @abstractmethod def config(self, settings: dict): pass class OutputMail(ABC): def send(self, data: str): print(f"send {data} to {['name']}") def config(self, settings: dict): = settings class OutputMessage(ABC): def send(self, data: str): print(f"send {data} to {['name']}") def config(self, settings: dict): = settings
The reason for using abstract base class here is that when output, it is not a simple call.send
Just the method, you also need to configure the output parameters.
So it is better to use abstract base classes with structures.
After adding the output, the analysis function in the previous section is also changed to:
#Analyze datadef analysis(i: InputData, o: OutputResult): data = i.get_data() print("Start the data...") data = ("get data from ", "") (data)
The test code is as follows:
if __name__ == "__main__": i = APIHandler() o = OutputMail() ({"name": "aaa@"}) analysis(i, o) print("\n") i = CSVHandler() o = OutputMessage() ({"name": "13911123456"}) analysis(i, o) print("\n") i = SqliteHandler() o = OutputMail() ({"name": "xyz@"}) analysis(i, o) print("\n")
Running results:
$ .\protocol_abc.py
get_data from API
Start processing data...
send API to aaa@
get_data from CSV
Start processing data...
send CSV to 13911123456
get_data from SQLITE DATABASE
Start processing data...
send SQLITE DATABASE to xyz@
3. Choice of both
When we are in actual development design, how should we chooseProtocol
andABC
Woolen cloth?
actually,Protocol
andABC
The choice between them is not black or white, which usually depends on the background of the project and your goals.
Generally speaking, we prefer to use the following situationsProtocol
:
- You are using existing code or want to integrate third-party libraries
- Flexibility is a priority, you don't want to enforce strict hierarchies
- Objects from irrelevant class hierarchies require shared behavior
The following situations are preferredABC
:
- A system is being designed from scratch and needs to be strengthened
- The relationship between classes is predictable, and inheritance makes sense
- Shared features or default behavior reduce duplication and improve consistency
4. Summary
Overall,Protocol
andABC
Not two tools that compete with each other, they are complementary.
I useProtocol
Transform type safety into legacy systems without the need for massive refactoring.
On the other hand, if I build a system where structure and consistency are crucial from scratch, I useABC
。
When deciding which one to use, consider the flexibility requirements and long-term goals of the project.
Protocol
Provides flexibility and seamless integration, whileABC
Helps build structure and consistency.
By understanding their respective strengths, you can choose the right way to build a robust, maintainable Python system.
This is the article about a brief analysis of the use of interfaces and abstract base classes in Python. For more related contents of Python interfaces and abstract base classes, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!