โมดูล collections.abc ให้ Abstract Base Classes (ABCs) สำหรับ Container Types ใช้สร้าง Custom Containers ที่มีพฤติกรรมมาตรฐาน
import collections.abc
ABCs หลักสำหรับ Containers
| ABC | Extends | Abstract Methods ที่ต้อง Implement |
|---|---|---|
Container | - | __contains__ |
Iterable | - | __iter__ |
Iterator | Iterable | __next__, __iter__ |
Sized | - | __len__ |
Callable | - | __call__ |
Collection | Sized, Iterable, Container | (All of above) |
Sequence | Collection | __getitem__, __len__ |
MutableSequence | Sequence | + __setitem__, __delitem__, insert |
Set | Collection | __contains__, __iter__, __len__ |
MutableSet | Set | + add, discard |
Mapping | Collection | __getitem__, __iter__, __len__ |
MutableMapping | Mapping | + __setitem__, __delitem__ |
ตัวอย่าง: Custom Set Implementation
import collections.abc
class ListSet(collections.abc.Set):
"""Set implemented with List (O(n) operations)"""
def __init__(self, iterable):
self._elements = []
for item in iterable:
if item not in self._elements:
self._elements.append(item)
def __contains__(self, value):
return value in self._elements
def __iter__(self):
return iter(self._elements)
def __len__(self):
return len(self._elements)
# ใช้งาน
set1 = ListSet('ABCDEF')
set2 = ListSet('DEFGHI')
# Set Operations มาจาก ABC ฟรี!
intersection = set1 & set2
print("Intersection:", list(intersection)) # ['D', 'E', 'F']
union = set1 | set2
print("Union:", list(union))
difference = set1 - set2
print("Difference:", list(difference))
ผลลัพธ์
Intersection: ['D', 'E', 'F'] Union: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'] Difference: ['A', 'B', 'C']
Mixin Methods (ฟรีจาก ABC)
เมื่อ Implement Abstract Methods แล้ว จะได้ Methods เหล่านี้ฟรี:
| ABC | Mixin Methods |
|---|---|
| Set | &, |, -, ^, <, >, <=, >=, isdisjoint() |
| MutableSet | + add(), discard(), clear(), pop(), update() |
| Mapping | keys(), values(), items(), get(), __eq__ |
| Sequence | index(), count(), __reversed__, __contains__ |
Register Virtual Subclass
ลงทะเบียน Class ให้เป็น Subclass โดยไม่ต้อง Inherit (Duck Typing)
class MyList:
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
def __getitem__(self, i):
return self.data[i]
def __iter__(self):
return iter(self.data)
# Register
collections.abc.Sequence.register(MyList)
# ตอนนี้ isinstance ทำงาน!
print(isinstance(MyList([1,2,3]), collections.abc.Sequence)) # True
print(issubclass(MyList, collections.abc.Sequence)) # True
Best Practices
- Inherit จาก ABC ที่เหมาะสม (ไม่ใช่ Object ธรรมดา)
- ใช้
@abstractmethodDecorator บน Methods ที่บังคับ - Implement Minimum Methods ให้ได้ Mixin Methods ฟรี
- ใช้
collections.abcสำหรับ Type Hints:def func(x: collections.abc.Sequence)