TGViewer
بنیاد پایتون کاران فارسی بنیاد پایتون کاران فارسی @psfarsi · 1.89K subscribers
Post #1404 2.53K
بنیاد پایتون کاران فارسی #سوال مشکل کد زیر از نظر type annotation چیست؟ def f(l: list[object], k: list[int]) -> None: l = k
بسیار خب بیایید به جواب این سوال بپردازیم:

جواب این سوال در واقع به سه موضوع کوواریانس (Covariance)، کونتراواریانس (Contravariance) و اینواریانس (Invariance) بر میگردد. این سه مفهوم، مفاهیم مهمی در نظریه‌ی نوع‌ها (type theory) و typing در زبان‌های برنامه‌نویسی هستند. این مفاهیم به چگونگی رابطه‌ی بین type های مختلف و subtypes های آن‌ها مربوط می‌شوند.

در ادامه مختصری از هر یک توضیح داده میشود :


1. Covariance

کوواریانس (Covariance) زمانی رخ می‌دهد که یک type از نوع B که subtype عه A است، قابل assign کردن به یک مجموعه (Collection) از نوع B باشد. به عبارت دیگر، در Covariance، اگر A یک نوع باشد و B نوعی باشد که از A ارث بری میکند، یک شیء از نوع B می‌تواند جایگزین یک شیء از نوع A شود.

برخی زبان ها مانند سی شارپ، جاوا، سی پلاس پلاس از این مفهوم استفاده میکنند.


2. Contravariance

مفهوم Contravariance برعکس Covariance است. در این حالت ما میتوانیم از نوع پایه یا base به جای subtype استفاده کنیم. به عبارت دیگر، در Contravariance، اگر A یک نوع باشد و B نوعی باشد که از A مشتق شده است، یک شیء از نوع A می‌تواند جایگزین یک شیء از نوع B شود.


3. Invariance

بر خلاف کوواریانس و کونتراواریانس، اینواریانس به این معنی است که یک نوع نمی‌تواند به یک نوع دیگری (حتی subtype یا supertype) تبدیل شود. به عبارت دیگر، اگر یک متغیر یا پارامتر از یک نوع خاص باشد، فقط می‌تواند همان نوع خاص را بپذیرد و نه نوعی دیگر.

بسیاری از ساختارهای داده در زبان‌های برنامه‌نویسی اینواریانس هستند.


حالا که این مفاهیم را فهمیدیم بیایید به سوال برگردیم:

ما تابعی به شکل زیر داریم:

def f(l: list[object], k: list[int]) -> None:
l = k


در این تابع ما دو پارامتر داریم:

- پارامتر l که لیستی از object ها است.
- پارامتر k که لیستی از int ها است.

در بدنه تابع، ما میخواهیم لیست k که از نوع [list[int است را به l که از نوع [list[object است، اختصاص دهیم.
در نگاه اول ممکن است به نظر برسد که این کد باید کار کند زیرا int نوعی object است. اما نکته ای که وجود دارد این است که لیست ها در پایتون از مفهوم Invariance بهره میبرند.

لیست‌ها و به طور کلی بیشتر نوع‌های Generic در پایتون invariance هستند.

این به این معنی است که شما نمی‌توانید [list[int را به [list[object تبدیل کنید، حتی اگر int نوعی object باشد.

* دلیل این خطا این است که اگر اجازه چنین کاری داده شود، ممکن است باعث بروز خطاهای runtime شود!
برای مثال، فرض کنید که بعد از تخصیص k به l، شما می‌خواهید یک مقدار str رو به لیست l اضافه کنید (str هم یک object هست) :

def f(l: list[object], k: list[int]) -> None:
l = k
l.append("a string")


در اینجا، l در واقع یک [list[int است (لیستی از اعداد صحیح) و اضافه کردن یک مقدار str به آن باعث خطا می‌شود.

یادگیری type annotation یکی از اون دسته بحثای جالب و گاهی پیچیده در پایتون است که پیشنهاد میشه حتما برید دنبال یادگیریش😁

موفق و پیروز باشید.
  • 👍 12
More from @psfarsi
  1. Oct 6, 2026🚀 هاست حرفه‌ای مخصوص ربات‌های تلگرامی 🇳🇱 سرور هلند (Leaseweb) ⚡️ تأخیر پایین و اتصال سر…
  2. Sep 16, 2026#خارج_از_بحث چرا چیزهایی که یاد می‌گیریم را به اشتراک بگذاریم؟ یکی از عادت‌هایی که می‌توان…
  3. Sep 11, 2026خب پس از همکاری و بحث و گفتگوی فوق العاده ای که درباره این سوال شد بریم سراغ جوابش همونطور…
  4. Sep 10, 2026فرض کنید ما این Schema رو داریم: class PostBase(BaseModel): title: str content: str catego…
  5. Aug 13, 2026در جنگو، از blank=True استفاده کنیم یا null=True ؟ یکی از اشتباهات رایج در طراحی مدل‌های D…
  6. Oct 26, 2025سرعت 5G همراه اول حق مینوازد 🔥 〰〰〰〰〰 🌐 Website: LearnSecurity.ir 🎓 Channel: @LearnSecur…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →