[{"data":1,"prerenderedAt":74},["ShallowReactive",2],{"qa-\u002Fpython\u002Foop\u002Fabc-protocols":3},{"page":4,"siblings":53,"blog":44},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":44,"seo":45,"seoDescription":46,"stem":47,"subtopic":48,"topic":49,"topicSlug":50,"updated":51,"__hash__":52},"qa\u002Fpython\u002Foop\u002Fabc-protocols.md","Abc Protocols",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"hard","md","Python","python",{},true,6,"\u002Fpython\u002Foop\u002Fabc-protocols",[23,28,32,36,40],{"id":24,"difficulty":25,"q":26,"a":27},"what-is-abc","medium","What is an abstract base class and what does @abstractmethod do?","An **abstract base class (ABC)** is a class that **can't be instantiated\ndirectly** and defines a set of methods subclasses **must implement**. You build\none by subclassing `abc.ABC` and decorating required methods with\n**`@abstractmethod`**. Python refuses to instantiate any subclass that leaves an\nabstract method unimplemented.\n\n```python\nfrom abc import ABC, abstractmethod\n\nclass Shape(ABC):\n    @abstractmethod\n    def area(self):            # subclasses MUST implement this\n        ...\n\nShape()                        # TypeError — can't instantiate abstract class\n\nclass Circle(Shape):\n    def __init__(self, r):\n        self.r = r\n    def area(self):            # concrete implementation\n        return 3.14159 * self.r ** 2\n\nCircle(2).area()               # 12.566... — works\n```\n\n`@abstractmethod` turns the \"must implement\" contract into an **enforced,\nload-time check** rather than a runtime `NotImplementedError` later. It defines\nan interface that subclasses are required to fulfill.\n",{"id":29,"difficulty":25,"q":30,"a":31},"why-use-abcs","Why use ABCs instead of just regular classes?","ABCs **enforce an interface** — they guarantee at instantiation time that\nsubclasses provide the required methods, catching mistakes **early** instead of\nblowing up deep in your code. They also document intent clearly and integrate\nwith `isinstance` checks, so callers can verify capabilities.\n\n```python\nfrom abc import ABC, abstractmethod\n\nclass Storage(ABC):\n    @abstractmethod\n    def save(self, key, value): ...\n    @abstractmethod\n    def load(self, key): ...\n\nclass FileStorage(Storage):\n    def save(self, key, value): ...\n    # forgot load() ...\n\nFileStorage()      # TypeError — flags the missing method immediately\nisinstance(FileStorage, type) and issubclass(FileStorage, Storage)  # True\n```\n\nUse an ABC when you have a **family of classes that must share a contract** and\nyou want that contract enforced. For looser, optional interfaces, plain duck\ntyping or a `Protocol` may fit better.\n",{"id":33,"difficulty":14,"q":34,"a":35},"collections-abc","What is collections.abc and how is it useful?","`collections.abc` provides the **standard ABCs for Python's container\nprotocols** — `Iterable`, `Iterator`, `Sequence`, `Mapping`, `Hashable`, and\nmore. You use them two ways: as a **base class** to inherit mixin methods, and\nin **`isinstance` checks** to test whether an object supports a protocol.\n\n```python\nfrom collections.abc import Iterable, Sequence, Mapping\n\nisinstance([1, 2], Iterable)   # True\nisinstance(\"abc\", Sequence)    # True\nisinstance({}, Mapping)        # True\n\nclass MyList(Sequence):        # inherit the protocol's mixin methods\n    def __init__(self, data):\n        self._data = data\n    def __getitem__(self, i):\n        return self._data[i]\n    def __len__(self):\n        return len(self._data)\n    # get __contains__, __iter__, __reversed__, index, count for FREE\n```\n\nSubclassing `Sequence` and implementing just `__getitem__` + `__len__` gives you\na fully functional sequence. Prefer these standard ABCs over inventing your own\nfor container-like types.\n",{"id":37,"difficulty":25,"q":38,"a":39},"duck-typing-vs-abcs","What is the difference between duck typing and ABCs?","**Duck typing** is \"if it walks like a duck and quacks like a duck, it's a\nduck\" — Python doesn't check the type, it just **tries the operation** and works\nif the needed methods exist. **ABCs add an explicit, enforced contract** on top,\nletting you assert membership and catch missing methods up front.\n\n```python\n# Duck typing — no declared interface, just call and hope:\ndef make_it_quack(thing):\n    thing.quack()          # works for ANYTHING with a quack() method\n\nclass Dog:\n    def quack(self): return \"woof-quack\"\nmake_it_quack(Dog())       # works — Dog \"is\" a duck here\n\n# ABC — explicit, checkable contract:\nfrom abc import ABC, abstractmethod\nclass Duck(ABC):\n    @abstractmethod\n    def quack(self): ...\n```\n\nDuck typing is flexible and Pythonic but defers errors to runtime; ABCs trade\nsome flexibility for **early enforcement and clear interfaces**. Use duck typing\nfor loose coupling, ABCs when you want guarantees.\n",{"id":41,"difficulty":14,"q":42,"a":43},"typing-protocol","What is typing.Protocol and how does it relate to duck typing?","`typing.Protocol` enables **structural typing** (\"static duck typing\"): a class\nsatisfies a protocol simply by **having the right methods\u002Fattributes** — no\nexplicit inheritance needed. Type checkers verify the structure **statically**,\ngiving you duck typing's flexibility **with** static safety. Add\n**`@runtime_checkable`** to also allow `isinstance` checks at runtime.\n\n```python\nfrom typing import Protocol, runtime_checkable\n\n@runtime_checkable\nclass Drawable(Protocol):\n    def draw(self) -> str: ...     # required shape, not inheritance\n\nclass Button:                      # does NOT inherit Drawable\n    def draw(self) -> str:\n        return \"[Button]\"\n\ndef render(item: Drawable) -> str: # type checker accepts Button\n    return item.draw()\n\nrender(Button())                   # works — structural match\nisinstance(Button(), Drawable)     # True — thanks to @runtime_checkable\n```\n\nUnlike ABCs, classes don't register or subclass anything — matching the\n**structure is enough**. Note `@runtime_checkable` only checks method\n**names\u002Fexistence**, not signatures. Use Protocols for flexible, statically\nverified interfaces; use ABCs when you need shared implementation or explicit\nregistration.\n",null,{"description":11},"Python interview questions on abstract base classes and @abstractmethod, why use ABCs, collections.abc, duck typing vs ABCs, and typing.Protocol for structural\u002Fstatic duck typing with runtime_checkable.","python\u002Foop\u002Fabc-protocols","Abstract Base Classes & Protocols","Object-Oriented Programming","oop","2026-06-18","ND9wrQMm980ybmmy5dud6WKKaNzHF-LWIzfyLRcQJ5Q",[54,58,61,65,69,73],{"subtopic":55,"path":56,"order":57},"Inheritance & the MRO","\u002Fpython\u002Foop\u002Finheritance",1,{"subtopic":59,"path":60,"order":12},"Classes, Instances & __init__","\u002Fpython\u002Foop\u002Fclasses",{"subtopic":62,"path":63,"order":64},"Dunder \u002F Magic Methods","\u002Fpython\u002Foop\u002Fdunder-methods",3,{"subtopic":66,"path":67,"order":68},"Methods & Properties","\u002Fpython\u002Foop\u002Fmethods-properties",4,{"subtopic":70,"path":71,"order":72},"Dataclasses & __slots__","\u002Fpython\u002Foop\u002Fdataclasses-slots",5,{"subtopic":48,"path":21,"order":20},1781808680313]