TIL: python Protocol and typing

Hi there,

I’m still learning a lot around Python, and I discovered Protocol some months ago and I wanted to write that down to not forget.

Protocol was created in Python 3.8 with the PEP 544. There a multiple protocols in python but the one I’m talking about is a way to define structural typing. Some of you will also call that implicit interface. We can use the Protocol class from the typing module. To not confuse you even more, I will explain that with a simple image.

If we consider you as a journalist and you are writing tech articles, week notes and many type of writing; you always have things you will do for your posts despite the type of them, for example, such as:

To make sure you not forget those things, let’s create a template, so you don’t forget them. This template will be your protocol.

With real code it should look like something like this:

from typing import Protocol

class Publishable(Protocol):

   def publish(self):
      pass

That’s it, you can use it on any types of posts you want without inheritating them. This means that an object conforms to a protocol by implementing the required methods. Here’s an example with the publish method:

class Article:
   def __init__(self, title: str):
      self.title = title

   def publish(self) -> None:
      # do something to publish
      pass

The class Article is now implementing the protocol Publishable with the addition of the required method publish.

The pro and cons of that are:

Pro

Cons

I guess right now you’re thinking, great but how do I use this Protocol? Good question!

Protocols are primarily used for type hinting and static type checking. This means you can use a protocol as a type annotation to indicate that an argument or variable must conform to a specific protocol.

If we retake our example, we will have this following code:

def publish_article(article: Article) -> None:
   article.publish()
   ...

In this case it’s only one Protocol used, but you could have multiple Protocols used.

class Draft(Protocol):

   def mark_as_draft(self):
      # do something to mark as draft
      pass

class DraftAndPublishable(Draft, Publishable):
   pass

In this example, we define a protocol named Draft with a mark_as_draft method. Then we define another protocol named DraftAndPublishable that combines both the Draft and Publishable protocols.

If you are familiar with the special methods __iter__ and __next__, if you implement both, then your object will use the Iterator protocol ✨ You can learn more on Real Python blog post related to Iterator Protocol.

To conclude with, Protocols provide a way to define structural typing in Python, allowing you to create interfaces without the need for explicit inheritance. They enable type checkers to verify that objects adhere to the defined protocols, enhancing code correctness and maintainability.

That’s it for now! I hope it will be useful for someone.