💠 PEP 750: Template Strings (T-Strings)
مدتی میشه که PEP 750 تایید شده و قراره در نسخه 3.14 پیاده بشه.
برای اولین بار قراره زمانی که از quotation (
تا الان string prefix های r, f, u و fr رو در پایتون داشتیم و حالا قراره t و tr رو هم در کد ها (مخصوصا در کد framework ها مشاهده کنید).
وجود template string ها در پایتون چیز جدید نیست. string.Template یا formatting در پایتون وجود داشتند و دارند. حتی templating engine هایی مثل jinja یا meko و حتی engine های مختص framework های محبوبی مثل django هم وجود داشتند و میشه گفت این مقوله مفهوم جدیدی به پایتون اضافه نمیکنه.
از زمانی که PEP 498 تایید شد و f-string به پایتون 3.6 اومد مقداری مفهوم template ها در کد ها مقداری کمرنگ شدند چون عمده نیازی که وجود داشت برای جایگذاری مستقیم داده در string ها بود و f-string این نیاز رو برطرف میکرد. از زمان معرفی PEP 701 استفاده از اونها بیشتر هم شد چون استفاده از اون رو به شدت آسونتر میکرد.
اما t-string ها مثل f-string ها عمل نمیکنند. میشه گفت t-string ها تمام قابلیت هایی که f-string ها داشتند رو دارند اما اگر نیاز شما به چیزی مشابه f-string ها هست که یک
همونطور که اشاره شد شما با استفاده از این syntax دیگه مستقیما یک string ندارید و مقداری از نوع Template برای شما برگردونده میشه. شما وقتی از f-string استفاده میکنید صرفا خروجی در اختیار شما قرار میگیره و عملا هیچ دسترسی مستقیمی به مقادیر داده شده به رشته ندارید، اما t-string ها اینطور نیستند.
میشه گفت که اگر f-string خروجی (بَعد) چیزی که میخواین باشه، t-string یک ساختار نگهدارنده برای شماست (قبل از ایجاد). ضمن اینکه استفاده مستقیم از f-string ها برای انجام کار هایی میتونست مشکلات امنیتی (مثل sql injection) بوجود بیاره اما اینجا با مدیریت بهتر میشه از این مشکلات امنیتی هم در امان بود.
چطور باید یک template ساده نوشت؟
خب، قطعا با خودتون گفتید که "این همون f-string نیست؟" که خب جواب به طور واضحی نه هست. اینجا متغیر t دیگه یک string نیست، یک Template هست.
این چه امکاناتی رو به ما میده؟
1. تفکیک قسمت های ثابت در رشته از متغیر های ورودی.
2. دسترسی مستقیم به ورودی ها (interpolations)، نوعتبدیل خواسته شده برای اونها (conversion)، نوع formatting خواسته شده برای اونها (format_spec) و حتی عبارت داده شده جهت جایگذاری!
در PEP 498 گفته شده "به همون دلیلی که متد bytes.format رو نداریم، یک prefix با عنوان fb هم برای f-string ها نداریم". این قاعده درحال حاضر به طور کامل برای t-string ها هم صدق میکنه و tb هم معنی نداره.
اما خب، همونطور که گفته شده این چیزی نیست که ازش چشمپوشی شده باشه و این برمیگرده به پیشنهادی که Steve Dower داد که مورد قبول واقع شد پس انتظار میره در آینده ترکیبی از bytes ها رو هم با این template ها شاهد باشیم.
حالا سوالی پیش میاد. اینکه چه زمانی از f-string استفاده کنیم و چه زمانی از t-string؟
وقتی داریم در مورد f-string ها حرف میزنیم یعنی در خروجی انتظار یک
ما برای استفاده از template ها نیاز به یک processor داریم. به طور خیلی ساده میشه گفت t-string ها به منظور ایجاد string ها استفاده نمیشن و از اونها به عنوان ساختاری که داده های مرتبط به رشته رو به طور منظم نگهداری میکنه میشه یاد کرد. به طور کلی زمانی از t-string استفاده میکنید که شیوه ایجاد متن شما هم مهم هست و نیاز دارید که بدونید چه object هایی به عنوان ورودی و در چه قالبی داده شدند. اینطور با دست باز قادر به validate کردن اونها هستید و عملا از نحوه ایجاد رشتهای که در نهایت قراره خروجی شما باشه آگاهید.
این یعنی t-string ها حتی string نیستند! برای گرفتن خروجی حتما به یک processor نیاز هست که درواقع صرفا استفاده کننده template ماست.
تا قبل از ارائه میتونید خودتون نسخهای که در cpython پیادهسازی شده رو build و استفاده کنید. همچنین میتونید نمونه هایی از استفاده از این قابلیت رو اینجا مشاهده کنید. پیشنهاد میشه logging.py, web.py و reuse.py و مخصوصا fstring رو برای درک بهتر این ویژگی مطالعه کنید.
✍️ *ژنرال*
🏷 #Python, #PEP, #TStrings, #template, #pep750, #strings
💎 Channel: @DevelopixPython
مدتی میشه که PEP 750 تایید شده و قراره در نسخه 3.14 پیاده بشه.
برای اولین بار قراره زمانی که از quotation (
"
) استفاده میکنید مقداری از جنس یک built-in type برای شما برگردونده نشه.تا الان string prefix های r, f, u و fr رو در پایتون داشتیم و حالا قراره t و tr رو هم در کد ها (مخصوصا در کد framework ها مشاهده کنید).
وجود template string ها در پایتون چیز جدید نیست. string.Template یا formatting در پایتون وجود داشتند و دارند. حتی templating engine هایی مثل jinja یا meko و حتی engine های مختص framework های محبوبی مثل django هم وجود داشتند و میشه گفت این مقوله مفهوم جدیدی به پایتون اضافه نمیکنه.
از زمانی که PEP 498 تایید شد و f-string به پایتون 3.6 اومد مقداری مفهوم template ها در کد ها مقداری کمرنگ شدند چون عمده نیازی که وجود داشت برای جایگذاری مستقیم داده در string ها بود و f-string این نیاز رو برطرف میکرد. از زمان معرفی PEP 701 استفاده از اونها بیشتر هم شد چون استفاده از اون رو به شدت آسونتر میکرد.
اما t-string ها مثل f-string ها عمل نمیکنند. میشه گفت t-string ها تمام قابلیت هایی که f-string ها داشتند رو دارند اما اگر نیاز شما به چیزی مشابه f-string ها هست که یک
str
برگردونه، واقعا لزومی نداره از t-string ها استفاده کنید چون فقط کار خودتون رو پیچیده کردید. وجود t-string ها ضربهای به ماهیت f-string ها و علت وجودشون نمیزنه چون مفهومی متفاوت رو ارائه میده.همونطور که اشاره شد شما با استفاده از این syntax دیگه مستقیما یک string ندارید و مقداری از نوع Template برای شما برگردونده میشه. شما وقتی از f-string استفاده میکنید صرفا خروجی در اختیار شما قرار میگیره و عملا هیچ دسترسی مستقیمی به مقادیر داده شده به رشته ندارید، اما t-string ها اینطور نیستند.
میشه گفت که اگر f-string خروجی (بَعد) چیزی که میخواین باشه، t-string یک ساختار نگهدارنده برای شماست (قبل از ایجاد). ضمن اینکه استفاده مستقیم از f-string ها برای انجام کار هایی میتونست مشکلات امنیتی (مثل sql injection) بوجود بیاره اما اینجا با مدیریت بهتر میشه از این مشکلات امنیتی هم در امان بود.
چطور باید یک template ساده نوشت؟
c = "DevelopixPython"
t = t"subscribe @{c}"
خب، قطعا با خودتون گفتید که "این همون f-string نیست؟" که خب جواب به طور واضحی نه هست. اینجا متغیر t دیگه یک string نیست، یک Template هست.
این چه امکاناتی رو به ما میده؟
1. تفکیک قسمت های ثابت در رشته از متغیر های ورودی.
2. دسترسی مستقیم به ورودی ها (interpolations)، نوعتبدیل خواسته شده برای اونها (conversion)، نوع formatting خواسته شده برای اونها (format_spec) و حتی عبارت داده شده جهت جایگذاری!
در PEP 498 گفته شده "به همون دلیلی که متد bytes.format رو نداریم، یک prefix با عنوان fb هم برای f-string ها نداریم". این قاعده درحال حاضر به طور کامل برای t-string ها هم صدق میکنه و tb هم معنی نداره.
اما خب، همونطور که گفته شده این چیزی نیست که ازش چشمپوشی شده باشه و این برمیگرده به پیشنهادی که Steve Dower داد که مورد قبول واقع شد پس انتظار میره در آینده ترکیبی از bytes ها رو هم با این template ها شاهد باشیم.
حالا سوالی پیش میاد. اینکه چه زمانی از f-string استفاده کنیم و چه زمانی از t-string؟
وقتی داریم در مورد f-string ها حرف میزنیم یعنی در خروجی انتظار یک
str
داریم که render شده. اما زمانی که در مورد template ها حرف میزنیم انتظار خروجی str نداریم.ما برای استفاده از template ها نیاز به یک processor داریم. به طور خیلی ساده میشه گفت t-string ها به منظور ایجاد string ها استفاده نمیشن و از اونها به عنوان ساختاری که داده های مرتبط به رشته رو به طور منظم نگهداری میکنه میشه یاد کرد. به طور کلی زمانی از t-string استفاده میکنید که شیوه ایجاد متن شما هم مهم هست و نیاز دارید که بدونید چه object هایی به عنوان ورودی و در چه قالبی داده شدند. اینطور با دست باز قادر به validate کردن اونها هستید و عملا از نحوه ایجاد رشتهای که در نهایت قراره خروجی شما باشه آگاهید.
این یعنی t-string ها حتی string نیستند! برای گرفتن خروجی حتما به یک processor نیاز هست که درواقع صرفا استفاده کننده template ماست.
تا قبل از ارائه میتونید خودتون نسخهای که در cpython پیادهسازی شده رو build و استفاده کنید. همچنین میتونید نمونه هایی از استفاده از این قابلیت رو اینجا مشاهده کنید. پیشنهاد میشه logging.py, web.py و reuse.py و مخصوصا fstring رو برای درک بهتر این ویژگی مطالعه کنید.
💎 Channel: @DevelopixPython
Please open Telegram to view this post
VIEW IN TELEGRAM
Python Enhancement Proposals (PEPs)
PEP 750 – Template Strings | peps.python.org
This PEP introduces template strings for custom string processing.
💠 PEP 749: Deferred Evaluation Of Annotations Using Descriptors
بعد از چند سال حالا PEP 649 به لطف ارائه خوب PEP 749 تایید شده و قراره تحولی رو در annotation ها داشته باشیم.
به این کد دقت کنید:
در حالت عادی چون نوع برگشتی method ما B هست و B هم تا اون لحظه تعریف نشده به
خب، این واقعا کثیف کاری بود. IDE ها به درستی میتونستند type ها رو تشخیص بدند و مفسر هم دیگه خطای
اما همونطور که گفته شد همه اونها به string تبدیل میشدند و اگر کد زیر خواسته میشد خروجی مطلوب (که خود کلاس B هست) داده نمیشد و در عوض
این یعنی مشکل. چرا؟ چون در صورتی که مقدار local باشه الزاما دیگه به متغیر ها دسترسی نداریم و حتی اگر دسترسی داشته باشیم باید اون رو eval کنیم که کار جالبی نیست.
راهحلی درحال اضافه شدن هست. در نسخه 3.14 باز هم از مفهوم lazy evaluation قراره استفاده دیگهای بشه. علت برخورد شما به
این یک تحول نسبتا بزرگ برای زبان پایتون هست، اللخصوص برای نویسندگان کتابخونه ها. ممکنه دیده باشید که به جای
چه اتفاقی برای
این موضوع حتی فراتر از این حرف ها هست و ما حتی یک module کاملا جدید رو قراره در stdlib داشته باشیم. همونطور که گفته شده استفاده از inspect برای دسترسی به annotation ها راه خوبی نیست چون واقعا سنگینه. پس حالا
ما تابهحال نوع خاصی برای annotation ها نداشتیم (نوع کلی) اما حالا داریم:
1. VALUE: همون مقدار پیشفرض که تا الان هم داشتیم
2. FORWARDREF: در صورت نبود مقدار مشخصی برای اسم به کار برده شده
3. STRING: مقدار متنی اونها (کاملا مناسب برای ابزار document کردن)
تنها مورد جدید ForwardRef هست. چه زمانی این نوع دیده میشه؟ زمانی که عملا هیچ چیزی با این name وجود نداشته باشه (قبلا در این شرایط
این موضوع هیچ تاثیر منفی روی std wrapper هایی مثل classmethod، staticmethod، functools.wraps و موارد دیگه قرار نیست بزاره و همه همگام میشن پس لازم نیست در این مورد نگران باشیم.
به طور خلاصه، تغییر سنگینی در انتظار نویسندگان کتابخونه های بزرگ هست اما بعد از اون نوشتن annotation ها واقعا خیلی راحت تر میشه و پایتون خیلی مهربون تر با این قضیه برخورد میکنه.
✍️ *ژنرال*
🏷 #Python, #PEP, #annotations, #typehint, #pep749, #NameError
💎 Channel: @DevelopixPython
بعد از چند سال حالا 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 ها واقعا خیلی راحت تر میشه و پایتون خیلی مهربون تر با این قضیه برخورد میکنه.
💎 Channel: @DevelopixPython
Please open Telegram to view this post
VIEW IN TELEGRAM
Python Enhancement Proposals (PEPs)
PEP 749 – Implementing PEP 649 | peps.python.org
This PEP supplements PEP 649 by providing various tweaks and additions to its specification:
💠 PEP 758 – Allow except and except* expressions without parentheses
با قبول PEP 758 حالا syntax جدیدی رو برای ساختار try-except در نسخه 3.14 داریم. این موضوع ساختار های مورد قبول فعلی رو تغییر نمیده و فقط ساختاری جدید رو اضافه میکنه.
ابتدا بهتره یک مرور ساده روی ساختار فعلی
اگر لازم بود که از چند exception استفاده کنیم اونها رو داخل پرانتز قرار میدادیم و با ساختار زیر از اون استفاده میکردیم:
یا به طور دقیق تر:
به شکل:
این PEP چیز بخصوصی رو به همراه نداره، تنها موردی که به این زبان اضافه میکنه اینه که از حالا در صورتی که از کلمه کلیدی
به طور خلاصه میتونیم بگیم که اگر تا الان کد زیر با SyntaxError برخورد میکرد، حالا در نسخه 3.14 به هیچ مشکلی برخورد نمیکنه و به درستی اجرا میشه:
اما باید توجه داشت که اگر لازم باشه از
دلیل اضافه شدن این امکان عمدتا مرتبط به خوانایی کد و ساده کردن قسمت هاست. استفاده از پرانتز باتوجه به نبود هیچ چیز اضافه دیگهای غیرضروری بنظر میرسید و باتوجه به سایر قسمت ها که اضافه کردن پرانتز در این شرایط رو اختیاری کردند، این تغییر کمک میکنه تا قسمت
✍️ *ژنرال*
🏷 #Python, #PEP, #except, #try, #pep785
💎 Channel: @DevelopixPython
با قبول PEP 758 حالا syntax جدیدی رو برای ساختار try-except در نسخه 3.14 داریم. این موضوع ساختار های مورد قبول فعلی رو تغییر نمیده و فقط ساختاری جدید رو اضافه میکنه.
ابتدا بهتره یک مرور ساده روی ساختار فعلی
except
داشته باشیم:except_block:
| "except" expression ["as" identifier] ":" block
| "except" "*" expression ["as" identifier] ":" block
اگر لازم بود که از چند exception استفاده کنیم اونها رو داخل پرانتز قرار میدادیم و با ساختار زیر از اون استفاده میکردیم:
except_block:
| "except" (expressions) ["as" identifier] ":" block
| "except" "*" (expressions) ["as" identifier] ":" block
یا به طور دقیق تر:
except_block:
| "except" "(" expression ("," expression)+ ")" [ "as" identifier ] ":" block
| "except" "*" "(" expression ("," expression)+ ")" [ "as" identifier ] ":" block
به شکل:
try:
risky_operation()
except (ValueError, TypeError, RndExcept):
handle_error()
این PEP چیز بخصوصی رو به همراه نداره، تنها موردی که به این زبان اضافه میکنه اینه که از حالا در صورتی که از کلمه کلیدی
as
استفاده نشه میتونیم از پرانتز ها صرفنظر کنیم. پس حالا ساختار های زیر رو در پایتون ممکنه ببینید:except_block:
| 'except' expressions ':' block
| 'except' '*' expressions ':' block
به طور خلاصه میتونیم بگیم که اگر تا الان کد زیر با SyntaxError برخورد میکرد، حالا در نسخه 3.14 به هیچ مشکلی برخورد نمیکنه و به درستی اجرا میشه:
try:
risky_operation()
except ValueError, TypeError, RndExcept:
handle_error()
اما باید توجه داشت که اگر لازم باشه از
as
و یک identifier استفاده بشه وجود پرانتز ها همچنان الزامی هستند.دلیل اضافه شدن این امکان عمدتا مرتبط به خوانایی کد و ساده کردن قسمت هاست. استفاده از پرانتز باتوجه به نبود هیچ چیز اضافه دیگهای غیرضروری بنظر میرسید و باتوجه به سایر قسمت ها که اضافه کردن پرانتز در این شرایط رو اختیاری کردند، این تغییر کمک میکنه تا قسمت
except
از ساختار کلی error handling در پایتون هم مقداری مشابه سایر قسمت ها بشه. به طور خلاصه میتونیم بگیم که اگر از python2 استفاده میکردید و به این شکل خطاها رو مدیریت میکردید، حالا باز هم مجاز به انجام این کار هستید.💎 Channel: @DevelopixPython
Please open Telegram to view this post
VIEW IN TELEGRAM
Python Enhancement Proposals (PEPs)
PEP 758 – Allow except and except* expressions without parentheses | peps.python.org
This PEP 1 proposes to allow unparenthesized except and except* blocks in Python’s exception handling syntax only when not using the as clause. Currently, when catching multiple exceptions, parentheses are required around the exception types. This was a...