Protocol در Python؛ بررسی سازگاری typeها بدون اجبار به inheritance

چرا مهم است

اگر تو با type hints کار می‌کنی، مهم است بدانی سازگاری classها همیشه به inheritance وابسته نیست. Protocol کمک می‌کند قابلیت‌های لازم را مشخص کنی و همان انعطاف duck typing را در static type checking هم داشته باشی.

قبل از خواندن، این‌ها را بدان۶ مفهوم
Protocol

قراردادی که methodها و attributeهای لازم برای سازگاری یک class با یک type را مشخص می‌کند، بدون اینکه لزوماً به inheritance نیاز باشد.

بیشتر درباره این مفهوم

structural subtyping

تعیین سازگاری typeها بر اساس methodها و attributeهای موجود در ساختار آن‌ها، نه صرفاً رابطهٔ inheritance.

بیشتر درباره این مفهوم

nominal subtyping

تعیین رابطهٔ typeها بر اساس رابطه‌های اعلام‌شده، مانند inheritance میان classها.

بیشتر درباره این مفهوم

نمایش همه (۶)
duck typing

روشی که در آن داشتن methodها و attributeهای موردنیاز، ملاک استفاده از یک object است، نه نام type آن.

بیشتر درباره این مفهوم

static type checking

بررسی سازگاری typeها بدون اجرای برنامه، با ابزارهایی مانند mypy، Pyright و Pyre و با کمک type hints.

بیشتر درباره این مفهوم

static duck typing

بررسی سازگاری ساختاری objectها پیش از اجرای برنامه؛ یعنی به‌کارگیری نگاه duck typing در static type checking.

بیشتر درباره این مفهوم

آموزش Real Python به نقش Protocol در type hints پایتون می‌پردازد: راهی برای مشخص‌کردن methodها و attributeهایی که یک class باید داشته باشد تا با یک type سازگار شناخته شود. نکتهٔ اصلی این است که این سازگاری می‌تواند بر پایهٔ ساختار class باشد، بدون آنکه رابطه‌ای از طریق inheritance برقرار شده باشد.

متن ابتدا دو کاربرد متفاوت واژهٔ Protocol در Python را روشن می‌کند. کاربرد قدیمی‌تر به قراردادهای داخلی مانند iterator، context manager و descriptor اشاره دارد؛ برای نمونه، methodهای __iter__() و __next__() قرارداد iterator را تعریف می‌کنند. کاربرد دوم که در Python 3.8 معرفی شد، به تعریف ساختاری اشاره دارد که classهای مختلف با داشتن methodها و attributeهای موردنیاز آن، می‌توانند جای یکدیگر استفاده شوند.

این موضوع با duck typing ارتباط مستقیم دارد. در duck typing، نام type یا جایگاه class در inheritance ملاک اصلی نیست؛ مهم این است که object قابلیت‌های لازم را داشته باشد. نمونهٔ متن، پیمایش روی list، tuple، string، dictionary و set است: با وجود تفاوت این typeها، همگی از iteration پشتیبانی می‌کنند.

Protocol این نگاه را به static type checking پیوند می‌دهد. طبق توضیح مقاله، ابزارهایی مانند mypy، Pyright و Pyre پیش از پشتیبانی از Protocol، برای بررسی رابطهٔ typeها به nominal subtyping مبتنی بر inheritance متکی بودند. structural subtyping این امکان را فراهم می‌کند که ساختار class بررسی شود؛ قابلیتی که متن از آن با عنوان static duck typing نیز یاد می‌کند.

آموزش کامل همچنین ساخت Protocol سفارشی با classِ Protocol و تفاوت آن با abstract base classes را در برنامهٔ خود دارد، اما بخش ارائه‌شده هنوز وارد جزئیات این مباحث نمی‌شود. برای دنبال‌کردن توضیحات و مثال‌های کامل، به مقالهٔ اصلی مراجعه کن: https://realpython.com/python-protocol/

نکته کلیدی

برای فهم سازگاری دو class، اول methodها و attributeهای موردنیاز را مشخص کن؛ فقط به inheritance نگاه نکن. تفاوت Protocol با قراردادهای داخلی مثل iterator را هم به خاطر بسپار، چون متن‌های Python از هر دو معنا استفاده می‌کنند.

خواندن مقاله اصلی (در زبانه‌ی جدید باز می‌شود)
برچسب‌ها (۴)