In this guide, you'll explore Python's collections.abc module, which defines abstract base classes for containers. Learn its features and examples for better code design.
The collections.abc
module in Python provides abstract base classes (ABCs) for various container types, allowing you to define and check for container interfaces. These ABCs are useful for type checking and ensuring that custom container types implement the necessary methods to behave like standard containers.
Table of Contents
- Introduction
- Container ABCs
Container
Hashable
Iterable
Iterator
Generator
Sized
Callable
Collection
Sequence
MutableSequence
ByteString
Set
MutableSet
Mapping
MutableMapping
MappingView
KeysView
ItemsView
ValuesView
- Examples
- Checking for Interface Compliance
- Creating a Custom Iterable
- Implementing a Custom Mutable Mapping
- Real-World Use Case
- Conclusion
- References
Introduction
The collections.abc
module provides a set of abstract base classes that define the fundamental interfaces for container types in Python. These interfaces ensure that custom container types provide the necessary methods to work seamlessly with the rest of Python's data model. By inheriting from these ABCs, you can create custom containers that are compatible with Python's standard containers.
Container ABCs
Container
The Container
class checks if an object supports the in
operator.
from collections.abc import Container
class MyContainer:
def __contains__(self, item):
return item in self.items
container = MyContainer()
print(isinstance(container, Container))
Output:
True
Hashable
The Hashable
class checks if an object supports hashing.
from collections.abc import Hashable
print(isinstance(42, Hashable))
print(isinstance([], Hashable))
Output:
True
False
Iterable
The Iterable
class checks if an object supports iteration.
from collections.abc import Iterable
print(isinstance([], Iterable))
print(isinstance({}, Iterable))
Output:
True
True
Iterator
The Iterator
class checks if an object supports iteration and the __next__
method.
from collections.abc import Iterator
it = iter([1, 2, 3])
print(isinstance(it, Iterator))
Output:
True
Generator
The Generator
class checks if an object is a generator.
from collections.abc import Generator
def gen():
yield 1
g = gen()
print(isinstance(g, Generator))
Output:
True
Sized
The Sized
class checks if an object has a __len__
method.
from collections.abc import Sized
print(isinstance([], Sized))
print(isinstance({}, Sized))
Output:
True
True
Callable
The Callable
class checks if an object is callable.
from collections.abc import Callable
print(isinstance(lambda x: x, Callable))
Output:
True
Collection
The Collection
class is a base class for collections that are iterable, sized, and container.
from collections.abc import Collection
print(isinstance([], Collection))
print(isinstance({}, Collection))
Output:
True
True
Sequence
The Sequence
class checks if an object supports sequence operations like indexing and slicing.
from collections.abc import Sequence
print(isinstance([], Sequence))
print(isinstance({}, Sequence))
Output:
True
False
MutableSequence
The MutableSequence
class checks if an object supports mutable sequence operations.
from collections.abc import MutableSequence
print(isinstance([], MutableSequence))
Output:
True
ByteString
The ByteString
class checks if an object supports byte string operations.
from collections.abc import ByteString
print(isinstance(b'abc', ByteString))
Output:
C:\Users\rames\AppData\Local\Temp\script16814326250219225151.py:3: DeprecationWarning: 'collections.abc.ByteString' is deprecated and slated for removal in Python 3.14
print(isinstance(b'abc', ByteString))
True
Set
The Set
class checks if an object supports set operations.
from collections.abc import Set
print(isinstance(set(), Set))
Output:
True
MutableSet
The MutableSet
class checks if an object supports mutable set operations.
from collections.abc import MutableSet
print(isinstance(set(), MutableSet))
Output:
True
Mapping
The Mapping
class checks if an object supports mapping (dictionary-like) operations.
from collections.abc import Mapping
print(isinstance({}, Mapping))
Output:
True
MutableMapping
The MutableMapping
class checks if an object supports mutable mapping operations.
from collections.abc import MutableMapping
print(isinstance({}, MutableMapping))
Output:
True
MappingView
The MappingView
class checks if an object supports mapping view operations.
KeysView
The KeysView
class checks if an object supports keys view operations.
ItemsView
The ItemsView
class checks if an object supports items view operations.
ValuesView
The ValuesView
class checks if an object supports values view operations.
Examples
Checking for Interface Compliance
Check if a custom container class conforms to the Sequence
interface.
from collections.abc import Sequence
class MyList:
def __getitem__(self, index):
return index
def __len__(self):
return 10
my_list = MyList()
print(isinstance(my_list, Sequence))
Output:
False
Creating a Custom Iterable
Create a custom iterable class.
from collections.abc import Iterable
class MyIterable(Iterable):
def __iter__(self):
yield from [1, 2, 3]
my_iterable = MyIterable()
for item in my_iterable:
print(item)
Output:
1
2
3
Implementing a Custom Mutable Mapping
Create a custom mutable mapping class.
from collections.abc import MutableMapping
class MyDict(MutableMapping):
def __init__(self):
self.store = dict()
def __getitem__(self, key):
return self.store[key]
def __setitem__(self, key, value):
self.store[key] = value
def __delitem__(self, key):
del self.store[key]
def __iter__(self):
return iter(self.store)
def __len__(self):
return len(self.store)
my_dict = MyDict()
my_dict['a'] = 1
my_dict['b'] = 2
print(my_dict['a'])
print(my_dict)
Output:
1
<__main__.MyDict object at 0x0000021902E165A0>
Real-World Use Case
Validating Data Structures
Suppose you are writing a function that processes various data structures. You can use the collections.abc
module to validate that the input conforms to the expected interfaces.
from collections.abc import Mapping, Sequence
def process_data(data):
if isinstance(data, Mapping):
print("Processing mapping data")
for key, value in data.items():
print(f"{key}: {value}")
elif isinstance(data, Sequence):
print("Processing sequence data")
for item in data:
print(item)
else:
raise TypeError("Unsupported data type")
process_data({'a': 1, 'b': 2})
process_data([1, 2, 3])
Output:
Processing mapping data
a: 1
b: 2
Processing sequence data
1
2
3
Conclusion
The collections.abc
module in Python provides a robust framework for defining and working with container interfaces. By leveraging these abstract base classes, you can ensure that your custom container types are fully compatible with Python's data model, making your code more flexible and interoperable.
Comments
Post a Comment
Leave Comment