| کانال توسعه‌دهندگان پایتون |
6.63K subscribers
38 photos
2 videos
4 files
43 links
⭕️ کانال توسعه‌دهندگان پایتون دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
💠 PEP 749: Deferred Evaluation Of Annotations Using Descriptors

بعد از چند سال حالا PEP 649 به لطف ارائه خوب PEP 749 تایید شده و قراره تحولی رو در annotation ها داشته باشیم.
به این کد دقت کنید:
class A:
def method(self) -> B: ...

class B: ...


در حالت عادی چون نوع برگشتی method ما B هست و B هم تا اون لحظه تعریف نشده به NameError برخورد میکنیم. این تا حد زیادی تبدیل به یک معضل شده بود تا اینکه اجازه استفاده از literal string ها به عنوان نوعی ارجاع دهنده داده شد که در __annotations__ هم لحاظ میشن. این موضوع حتی فراتر از این حدود هم پیش رفت و با ارائه PEP 563 و امکان استفاده از annotations در __future__، تمام annotation ها هنگام اجرای کد (runtime) تبدیل به string میشن (بدون استثنا، تمام annotation ها).

خب، این واقعا کثیف کاری بود. IDE ها به درستی میتونستند type ها رو تشخیص بدند و مفسر هم دیگه خطای NameError نمیداد:
from __future__ import annotations

class A:
def method(self) -> B: ...

class B: ...


اما همونطور که گفته شد همه اونها به string تبدیل میشدند و اگر کد زیر خواسته میشد خروجی مطلوب (که خود کلاس B هست) داده نمیشد و در عوض "B" رو میدیدم.
print(A.method.__annotations__)


این یعنی مشکل. چرا؟ چون در صورتی که مقدار local باشه الزاما دیگه به متغیر ها دسترسی نداریم و حتی اگر دسترسی داشته باشیم باید اون رو eval کنیم که کار جالبی نیست.

راه‌حلی درحال اضافه شدن هست. در نسخه 3.14 باز هم از مفهوم lazy evaluation قراره استفاده دیگه‌ای بشه. علت برخورد شما به NameError در کد اول این هست که مفسر بلافاصله میخواد به annotation دسترسی پیدا کنه، اما حالا این کار رو انجام نمیده و فقط زمانی که باید بهشون دسترسی گرفته بشه این کار رو انجام میده که باعث میشه موقع load کردن code شما حتی اگر annotation وجود خارجی هم نداشت باعث مشکل نشه.

این یک تحول نسبتا بزرگ برای زبان پایتون هست، اللخصوص برای نویسندگان کتابخونه ها. ممکنه دیده باشید که به جای SomeType نوشته شده باشه "SomeType" چرا؟ چون به هر دلیلی نویسنده خواسته از NameError فرار کنه. اما حالا نه، لازم نیست quote قرار داده بشه و مستقیما میشه از خودش استفاده کرد.

چه اتفاقی برای annotations در __future__ میوفته؟ در نسخه 3.15 حذف میشه و احتمالا هشدار منسوخ شدن برای استفاده از اون در نسخه 3.14 اضافه خواهد شد.

این موضوع حتی فراتر از این حرف ها هست و ما حتی یک module کاملا جدید رو قراره در stdlib داشته باشیم. همونطور که گفته شده استفاده از inspect برای دسترسی به annotation ها راه خوبی نیست چون واقعا سنگینه. پس حالا annotationlib رو قراره داشته باشیم که ابزاری کاملا مناسب هست و به راحتی قابل استفاده‌ست.

ما تابه‌حال نوع خاصی برای annotation ها نداشتیم (نوع کلی) اما حالا داریم:

‏1. VALUE: همون مقدار پیش‌فرض که تا الان هم داشتیم
‏2. FORWARDREF: در صورت نبود مقدار مشخصی برای اسم به کار برده شده
‏3. STRING: مقدار متنی اونها (کاملا مناسب برای ابزار document کردن)

تنها مورد جدید ForwardRef هست. چه زمانی این نوع دیده میشه؟ زمانی که عملا هیچ چیزی با این name وجود نداشته باشه (قبلا در این شرایط NameError داده میشد) و حالا با این نوع گفته میشه که "این نوع unresolved هست"

این موضوع هیچ تاثیر منفی روی std wrapper هایی مثل classmethod، staticmethod، functools.wraps و موارد دیگه قرار نیست بزاره و همه همگام میشن پس لازم نیست در این مورد نگران باشیم.

به طور خلاصه، تغییر سنگینی در انتظار نویسندگان کتابخونه های بزرگ هست اما بعد از اون نوشتن annotation ها واقعا خیلی راحت تر میشه و پایتون خیلی مهربون تر با این قضیه برخورد میکنه.

✍️ *ژنرال*

🏷 #Python, #PEP, #annotations, #typehint, #pep749, #NameError

💎 Channel: @DevelopixPython
Please open Telegram to view this post
VIEW IN TELEGRAM