collections.abc --- کلاس‌های پایه انتزاعی برای ظروف

اضافه شده در نسخه‌ی 3.3: پیش‌تر، این ماژول بخشی از ماژول collections بود.

کد منبع: Lib/_collections_abc.py


این ماژول کلاس‌های پایه انتزاعی را فراهم می‌کند که می‌توان از آن‌ها برای بررسی این‌که آیا یک کلاس رابط خاصی را ارائه می‌دهد استفاده کرد؛ برای مثال، این‌که آیا هش‌پذیر است یا یک نگاشت است.

یک آزمون issubclass() یا isinstance() برای یک رابط به یکی از سه روش عمل می‌کند.

  1. یک کلاس تازه‌نوشته‌شده می‌تواند مستقیماً از یکی از کلاس‌های پایه انتزاعی ارث ببرد. این کلاس باید متدهای انتزاعی مورد نیاز را فراهم کند. متدهای میکس‌این باقی‌مانده از طریق ارث‌بری به دست می‌آیند و در صورت تمایل می‌توان آن‌ها را بازنویسی کرد. در صورت نیاز، می‌توان متدهای دیگری اضافه کرد:

    class C(Sequence):                      # Direct inheritance
        def __init__(self): ...             # Extra method not required by the ABC
        def __getitem__(self, index):  ...  # Required abstract method
        def __len__(self):  ...             # Required abstract method
        def count(self, value): ...         # Optionally override a mixin method
    
    >>> issubclass(C, Sequence)
    True
    >>> isinstance(C(), Sequence)
    True
    
  2. کلاس‌های موجود و کلاس‌های توکار می‌توانند به‌عنوان «زیرکلاس‌های مجازی» ABCها ثبت شوند. آن کلاس‌ها باید API کامل را، شامل تمام متدهای انتزاعی و تمام متدهای میکس‌این، تعریف کنند. این امر به کاربران اجازه می‌دهد برای تعیین اینکه آیا رابط کامل پشتیبانی می‌شود، به آزمون‌های issubclass() یا isinstance() اتکا کنند. استثنای این قاعده برای متدهایی است که به‌طور خودکار از باقی API استنتاج می‌شوند:

    class D:                                 # No inheritance
        def __init__(self): ...              # Extra method not required by the ABC
        def __getitem__(self, index):  ...   # Abstract method
        def __len__(self):  ...              # Abstract method
        def count(self, value): ...          # Mixin method
        def index(self, value): ...          # Mixin method
    
    Sequence.register(D)                     # Register instead of inherit
    
    >>> issubclass(D, Sequence)
    True
    >>> isinstance(D(), Sequence)
    True
    

    در این مثال، کلاس D نیازی به تعریف __contains__، __iter__ و __reversed__ ندارد، زیرا عملگر in، منطق پیمایش و تابع reversed() به‌طور خودکار به استفاده از __getitem__ و __len__ بازمی‌گردند.

  3. برخی رابط‌های ساده مستقیماً از روی وجود متدهای مورد نیاز قابل تشخیص هستند (مگر آنکه آن متدها روی None تنظیم شده باشند):

    class E:
        def __iter__(self): ...
        def __next__(self): ...
    
    >>> issubclass(E, Iterable)
    True
    >>> isinstance(E(), Iterable)
    True
    

    رابط‌های پیچیده از این روش آخر پشتیبانی نمی‌کنند، زیرا یک رابط چیزی فراتر از صرف وجود نام متدها است. رابط‌ها معناشناسی و روابط میان متدها را مشخص می‌کنند، که نمی‌توان آن‌ها را صرفاً از وجود نام متدهای خاص استنتاج کرد. برای مثال، دانستن اینکه یک کلاس __getitem__، __len__ و __iter__ را فراهم می‌کند، برای تمایز Sequence از Mapping کافی نیست.

اضافه شده در نسخه‌ی 3.9: این کلاس‌های انتزاعی اکنون از [] پشتیبانی می‌کنند. Generic Alias Type و PEP 585 را ببینید.

کلاس‌های پایه انتزاعی مجموعه‌ها

ماژول collections کلاس‌های پایه انتزاعی زیر را ارائه می‌دهد:

ABC

به ارث می‌برد از

متدهای انتزاعی

متدهای میکس‌این

Container [1]

__contains__

Hashable [1]

__hash__

Iterable [1] [2]

__iter__

Iterator [1]

Iterable

__next__

__iter__

Reversible [1]

Iterable

__reversed__

Generator [1]

Iterator

send, throw

close, __iter__, __next__

Sized [1]

__len__

Callable [1]

__call__

Collection [1]

Sized, Iterable, Container

__contains__, __iter__, __len__

Sequence

Reversible, Collection

__getitem__, __len__

__contains__، __iter__، __reversed__، index و count

MutableSequence

Sequence

__getitem__, __setitem__, __delitem__, __len__, insert

متدهای به ارث رسیده از Sequence و append، clear، reverse، extend، pop، remove و __iadd__

ByteString

Sequence

__getitem__, __len__

متدهای موروثی Sequence

Set

Collection

__contains__, __iter__, __len__

__le__، __lt__، __eq__، __ne__، __gt__، __ge__، __and__، __or__، __sub__، __rsub__، __xor__، __rxor__ و isdisjoint

MutableSet

Set

__contains__, __iter__, __len__, add, discard

متدهای به‌ارث‌رسیده از Set و clear، pop، remove، __ior__، __iand__، __ixor__ و __isub__

Mapping

Collection

__getitem__, __iter__, __len__

__contains__، keys، items، values، get، __eq__ و __ne__

MutableMapping

Mapping

__getitem__, __setitem__, __delitem__, __iter__, __len__

متدهای به‌ارث‌رسیده از Mapping و pop، popitem، clear، update و setdefault

MappingView

Sized

__init__، __len__ و __repr__

ItemsView

MappingView, Set

__contains__, __iter__

KeysView

MappingView, Set

__contains__, __iter__

ValuesView

MappingView, Collection

__contains__, __iter__

Awaitable [1]

__await__

Coroutine [1]

Awaitable

send, throw

close

AsyncIterable [1]

__aiter__

AsyncIterator [1]

AsyncIterable

__anext__

__aiter__

AsyncGenerator [1]

AsyncIterator

asend, athrow

aclose, __aiter__, __anext__

Buffer [1]

__buffer__

پانویس‌ها

کلاس‌های پایه انتزاعی مجموعه‌ها -- توضیحات تفصیلی

class collections.abc.Container

کلاس پایه انتزاعی (ABC) برای کلاس‌هایی که متد __contains__() را فراهم می‌کنند.

class collections.abc.Hashable

کلاس پایه انتزاعی (ABC) برای کلاس‌هایی که متد __hash__() را ارائه می‌دهند.

class collections.abc.Sized

کلاس پایه انتزاعی (ABC) برای کلاس‌هایی که متد __len__() را فراهم می‌کنند.

class collections.abc.Callable

ABC برای کلاس‌هایی که متد __call__() را فراهم می‌کنند.

برای جزئیات درباره‌ی نحوه‌ی استفاده از Callable در حاشیه‌نویسی‌های نوع، حاشیه‌نویسی اشیاء فراخوانی‌پذیر را ببینید.

class collections.abc.Iterable

کلاس پایه انتزاعی (ABC) برای کلاس‌هایی که متد __iter__() را فراهم می‌کنند.

بررسی isinstance(obj, Iterable) کلاس‌هایی را که به‌عنوان Iterable ثبت شده‌اند یا دارای متد __iter__() هستند تشخیص می‌دهد، اما کلاس‌هایی را که پیمایش آن‌ها از طریق متد __getitem__() انجام می‌شود تشخیص نمی‌دهد. تنها راه قابل‌اطمینان برای تشخیص اینکه آیا یک شیء پیمایش‌پذیر است، فراخوانی iter(obj) است.

class collections.abc.Collection

کلاس پایه انتزاعی (ABC) برای کلاس‌های ظرف اندازه‌دار و پیمایش‌پذیر.

اضافه شده در نسخه‌ی 3.6.

class collections.abc.Iterator

ABC برای کلاس‌هایی که متدهای __iter__() و __next__() را فراهم می‌کنند. همچنین تعریف iterator را ببینید.

class collections.abc.Reversible

ABC برای کلاس‌های پیمایش‌پذیری که متد __reversed__() را نیز ارائه می‌دهند.

اضافه شده در نسخه‌ی 3.6.

class collections.abc.Generator

کلاس پایه انتزاعی (ABC) برای کلاس‌های تولیدگر که پروتکل تعریف‌شده در PEP 342 را پیاده‌سازی می‌کنند؛ پروتکلی که پیمایش‌گرها را با متدهای send()، throw() و close() گسترش می‌دهد.

برای جزئیات درباره استفاده از Generator در حاشیه‌نویسی‌های نوع، حاشیه‌نویسی تولیدگرها و هم‌روال‌ها را ببینید.

اضافه شده در نسخه‌ی 3.5.

class collections.abc.Sequence
class collections.abc.MutableSequence
class collections.abc.ByteString

کلاس‌های پایه انتزاعی (ABC) برای دنباله‌های فقط‌خواندنی و تغییرپذیر.

یادداشت پیاده‌سازی: برخی از متدهای میکس‌این، مانند __iter__()، __reversed__() و index()، فراخوانی‌های مکرری به متد زیربنایی __getitem__() انجام می‌دهند. در نتیجه، اگر __getitem__() با سرعت دسترسی ثابت پیاده‌سازی شده باشد، متدهای میکس‌این عملکرد خطی خواهند داشت؛ اما اگر متد زیربنایی خطی باشد (همان‌طور که در یک فهرست پیوندی این‌گونه خواهد بود)، میکس‌این‌ها عملکرد درجه دو خواهند داشت و احتمالاً لازم است بازنویسی شوند.

index(value, start=0, stop=None)

نخستین اندیس value را برمی‌گرداند.

اگر مقدار موجود نباشد، ValueError پرتاب می‌شود.

پشتیبانی از آرگومان‌های start و stop اختیاری است، اما توصیه می‌شود.

تغییر یافته در نسخه‌ی 3.5: پشتیبانی از آرگومان‌های stop و start به متد index() اضافه شد.

منسوخ شده از نسخه‌ی 3.12, در نسخه‌ی 3.17 حذف خواهد شد: کلاس پایه انتزاعی (ABC) ByteString منسوخ شده است.

برای بررسی اینکه obj پروتکل بافر را در زمان ران‌تایم پیاده‌سازی می‌کند، از isinstance(obj, collections.abc.Buffer) استفاده کنید. برای استفاده در حاشیه‌نویسی‌های نوع، یا از Buffer استفاده کنید یا از یک اجتماع (union) که به‌صراحت انواع مورد پشتیبانی کد شما را مشخص می‌کند (مثلاً bytes | bytearray | memoryview).

ByteString در ابتدا قرار بود یک کلاس انتزاعی باشد که به‌عنوان نوع والد هر دو کلاس bytes و bytearray عمل کند. با این حال، از آنجا که این کلاس پایه انتزاعی هرگز هیچ متدی نداشت، دانستن این‌که یک شیء نمونه‌ای از ByteString است، در عمل هرگز اطلاعات مفیدی درباره‌ی آن شیء به شما نمی‌داد. سایر انواع رایج بافر مانند memoryview نیز هرگز به‌عنوان زیرنوع‌هایی از ByteString در نظر گرفته نمی‌شدند (نه در ران‌تایم و نه توسط بررسی‌کننده‌های نوع ایستا).

برای جزئیات بیشتر PEP 688 را ببینید.

class collections.abc.Set
class collections.abc.MutableSet

کلاس‌های پایه انتزاعی برای مجموعه‌های فقط‌خواندنی و تغییرپذیر.

class collections.abc.Mapping
class collections.abc.MutableMapping

کلاس‌های پایه انتزاعی برای نگاشت‌های فقط‌خواندنی و تغییرپذیر.

class collections.abc.MappingView
class collections.abc.ItemsView
class collections.abc.KeysView
class collections.abc.ValuesView

کلاس‌های پایه انتزاعی (ABCs) برای نماهای نگاشت، آیتم‌ها، کلیدها و مقدارها.

class collections.abc.Awaitable

کلاس پایه انتزاعی (ABC) برای اشیاء awaitable، که می‌توان از آن‌ها در عبارت‌های await استفاده کرد. پیاده‌سازی‌های سفارشی باید متد __await__() را فراهم کنند.

اشیاء هم‌روال و نمونه‌های کلاس پایه انتزاعی (ABC) Coroutine، همگی نمونه‌هایی از این ABC هستند.

توجه

در CPython، هم‌روال‌های مبتنی بر تولیدگر (تولیدگرها که با @types.coroutine دکور شده‌اند) awaitable هستند، اگرچه متد __await__() ندارند. استفاده از isinstance(gencoro, Awaitable) برای آن‌ها False را برمی‌گرداند. برای شناسایی آن‌ها از inspect.isawaitable() استفاده کنید.

اضافه شده در نسخه‌ی 3.5.

class collections.abc.Coroutine

ABC برای کلاس‌های سازگار با هم‌روال. این کلاس‌ها متدهای زیر را، که در اشیاء هم‌روال تعریف شده‌اند، پیاده‌سازی می‌کنند: send()، throw() و close(). پیاده‌سازی‌های سفارشی باید __await__() را نیز پیاده‌سازی کنند. تمام نمونه‌های Coroutine نیز نمونه‌هایی از Awaitable هستند.

توجه

در CPython، هم‌روال‌های مبتنی بر تولیدگر (تولیدگرها که با @types.coroutine آراییده شده‌اند) awaitable هستند، اگرچه آن‌ها متد __await__() ندارند. استفاده از isinstance(gencoro, Coroutine) برای آن‌ها False را برمی‌گرداند. برای تشخیص آن‌ها از inspect.isawaitable() استفاده کنید.

برای جزئیات درباره‌ی استفاده از Coroutine در حاشیه‌نویسی‌های نوع، حاشیه‌نویسی تولیدگرها و هم‌روال‌ها را ببینید. واریانس و ترتیب پارامترهای نوع، متناظر با موارد مربوط به Generator است.

اضافه شده در نسخه‌ی 3.5.

class collections.abc.AsyncIterable

ABC برای کلاس‌هایی که متد __aiter__ را ارائه می‌دهند. همچنین تعریف پیمایش‌پذیر ناهمگام را ببینید.

اضافه شده در نسخه‌ی 3.5.

class collections.abc.AsyncIterator

کلاس پایه انتزاعی (ABC) برای کلاس‌هایی که متدهای __aiter__ و __anext__ را فراهم می‌کنند. همچنین تعریف asynchronous iterator را ببینید.

اضافه شده در نسخه‌ی 3.5.

class collections.abc.AsyncGenerator

ABC برای کلاس‌های asynchronous generator که پروتکل تعریف‌شده در PEP 525 و PEP 492 را پیاده‌سازی می‌کنند.

برای جزئیات درباره‌ی استفاده از AsyncGenerator در حاشیه‌نویسی‌های نوع، حاشیه‌نویسی تولیدگرها و هم‌روال‌ها را ببینید.

اضافه شده در نسخه‌ی 3.6.

class collections.abc.Buffer

کلاس پایه انتزاعی (ABC) برای کلاس‌هایی که متد __buffer__() را ارائه می‌دهند و پروتکل بافر را پیاده‌سازی می‌کنند. PEP 688 را ببینید.

اضافه شده در نسخه‌ی 3.12.

مثال‌ها و راهکارها

کلاس‌های پایه انتزاعی (ABCs) به ما امکان می‌دهند از کلاس‌ها یا نمونه‌ها بپرسیم که آیا قابلیت خاصی را فراهم می‌کنند یا خیر، برای مثال:

size = None
if isinstance(myvar, collections.abc.Sized):
    size = len(myvar)

برخی از کلاس‌های پایه انتزاعی (ABC) نیز به‌عنوان میکس‌این مفید هستند و توسعه کلاس‌هایی را که از APIهای ظرف پشتیبانی می‌کنند، آسان‌تر می‌کنند. برای مثال، برای نوشتن کلاسی که از API کامل Set پشتیبانی می‌کند، تنها لازم است سه متد انتزاعی زیربنایی را فراهم کنید: __contains__()، __iter__() و __len__(). ABC متدهای باقی‌مانده مانند __and__() و isdisjoint() را فراهم می‌کند:

class ListBasedSet(collections.abc.Set):
    ''' Alternate set implementation favoring space over speed
        and not requiring the set elements to be hashable. '''
    def __init__(self, iterable):
        self.elements = lst = []
        for value in iterable:
            if value not in lst:
                lst.append(value)

    def __iter__(self):
        return iter(self.elements)

    def __contains__(self, value):
        return value in self.elements

    def __len__(self):
        return len(self.elements)

s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2            # The __and__() method is supported automatically

نکاتی درباره‌ی استفاده از Set و MutableSet به‌عنوان میکس‌این :

  1. از آنجا که برخی از عملیات مجموعه‌ای، مجموعه‌های جدیدی ایجاد می‌کنند، متدهای پیش‌فرض میکس‌این به راهی برای ایجاد نمونه‌های جدید از یک پیمایش‌پذیر نیاز دارند. فرض می‌شود که سازنده‌ی کلاس، امضایی به شکل ClassName(iterable) داشته باشد. این فرض در قالب یک classmethod داخلی به نام _from_iterable() استخراج شده است که cls(iterable) را فراخوانی می‌کند تا یک مجموعه جدید تولید کند. اگر از میکس‌این Set در کلاسی با امضای سازنده متفاوت استفاده شود، لازم است _from_iterable() را با یک classmethod یا متد معمولی که بتواند نمونه‌های جدید را از یک آرگومان پیمایش‌پذیر بسازد، بازنویسی کنید.

  2. برای بازنویسی مقایسه‌ها (احتمالاً برای سرعت، زیرا معنای آن‌ها ثابت است)، __le__() و __ge__() را بازتعریف کنید؛ سپس سایر عملیات به‌طور خودکار از آن‌ها پیروی خواهند کرد.

  3. میکس‌این Set یک متد _hash() برای محاسبه‌ی مقدار هش مجموعه ارائه می‌کند؛ با این حال، __hash__() تعریف نشده است، زیرا همه‌ی مجموعه‌ها هش‌پذیر یا تغییرناپذیر نیستند. برای افزودن هش‌پذیری مجموعه با استفاده از میکس‌این‌ها، از هر دو Set و Hashable ارث‌بری کنید، سپس __hash__ = Set._hash را تعریف کنید.

همچنین ملاحظه نمائید