مروری بر تغییرات پایتون ۳.۹

نسخه‌ی پایدار پایتون ۳.۹، تو تاریخ ۵ اکتبر منتشر شد، تو این پست یه مرور کوتاه و کلی روی تغییرات جدیدی که روی پایتون ۳.۹ اعمال شده با هم انجام می‌دیم.Photo by Christina Morillo from Pexels ? امکانات سینتکسی جدید— PEP 584: Union operators added to &amp;amp;#x60;dict&amp;amp;#x60;— PEP 585: Type hinting generics in standard collections— PEP 614: Relaxed grammar restrictions on decoratorsاین ۳تا PEP، امکانات جدید سینتکسی رو به صورت کامل توضیح می‌دن، هر کدومش رو اینجا به صورت خلاصه مرور می‌کنیم? PEP 584, union operators added to dictیه Operator یا عمل‌گر جدید برای `dict` اضافه شده، کار این عمل‌گر Merge کردن ۲ یا چند `dict` هستبرای مثال:personal_info = {'name': 'John', 'lastName': 'Doe'}address_info = {'country': 'Doeland'}اگر بخوایم این ۲ dict رو با هم یکی کنیم، تا قبل پایتون ۳.۹ با این روش انجام می‌دادیمuser_info = {**personal_info, **address_info}و مقدار `user_info` می‌شد{'name': 'John', 'lastName': 'Doe', 'country': 'Doeland'}تو نسخه‌ی ۳.۹ با استفاده از Pipe می‌تونیم همین کار رو بکنیمuser_info = personal_info | address infoبرای Assignment هم، همین Operator اضافه شده، مثال قبلی رو در نظر بگیرید، اما با این فرق که به جای `user_info` می‌خوایم، مقادیر `address_info` رو داخل `personal_info` بریزیمpersonal_info |= address_infoتوی این حالت، تمام keyهای address_info داخل personal_info هم Merge میشن، قبلا برای انجام این‌کار می‌تونستیم از متود `update` استفاده کنیمpersonal_info.update(address_info)? PEP 585 type hinting generics in standard collectionsاز پایتون ۳.۵، به پایتون Type Hinting اضافه شد.برای مثال شما یه تابع تعریف کردید به این شکلdef round_and_sum(x, y): return round(x) + round(y)داخل بدنه‌ی تابع، ویرایشگر یا IDE شما هیچ ایده‌ای نداره که پارامتر‌های `x` و `y` از چه نوعی هستن تا طبق Data Typeشون بهتون Auto Completion بدهبرای حل این مشکل، می‌تونیم روی تعریف پارامتر‌ها بهشون Type بدیمdef round_and_sum(x: float, y: float): return round(x) + rount(y)تو مشخص کردن نوع `x` و `y`، اگر داخل بدنه‌ی تابع، جلوشون نقطه بزاریم، بهمون متود‌های مختلف float رو پیشنهاد می‌ده، این موارد صرفا زمان Type Checking وجود دارن و تاثیری توی Runtime ندارنتوی این مثال، از float استفاده کردیم، که یک تایپ سادست، خودش چیزی رو داخل خودش نگه نمی‌داره، همین مثال رو با استفاده از Iteratorها می‌زنیم و با Generic Typeها آشنا می‌شیمfrom typing import Tuple def round_and_sum(*args: Tuple[float]): result = 0 for arg in args: result += round(arg) return resultبا توجه به این که `*args` یک Iterable هست از نوع Tuple، نوع خودش مشخص هست، اما نوع مقادیری که داخلش هستن مشخص نیست، باید براش از تایپ Generic که براش ارائه شده استفاده کرد، تایپ‌های Generic، یک تایپی رو به عنوان پارامتر خودشون می‌گیرن، توی مثال بالا، پارامتری که به تایپ Tuple دادم، float هستبه این شکل، اگر من داخل بدنه‌ی تابع بعدش از `args` نقطه بذارم، بهم متود‌های مربوط به `tuple` رو میده، اگر هم جلوی `args[0]` برای مثال، نقطه بذارم، بهم متود‌های `float` رو نشون میدهو اما تغییر PEP-585تا نسخه‌ی ۳.۸ برای تایپ‌های Generic باید از کتاب‌خونه‌ی Typing استفاده می‌کردید، تو نسخه‌ی ۳.۹ برای تایپ‌های Generic هم می‌تونید از همون کلاس استفاده کنیدمثال قبلی رو تو پایتون ۳.۹ می‌نویسمdef round_and_sum(*args: tuple[float]): result = 0 for arg in args: result += round(arg) return resultهمینطور که مشخصه، دیگه نیاز به Import نداره? PEP 614, Relaxed grammar restrictions on decoratorsتا قبل از پایتون ۳.۹، اگر داخل یه Class، یه Decorator تعریف می‌کردید، نمی‌تونستید هم‌زمان هم از Decorator استفاده کنید و هم از Classتون Object بسازیدیه مثال می‌زنم ساده‌تر درک کنیدclass Test: def __init__(self, namespace): self.namespace = namespace def my_decorator(self, function): def wrapper(*args, **kwargs): print(f'{self.namespace} => {function.__name__} is running.') return function(*args, **kwargs) return wrapperمن اینجا یه کلاس تعریف کردم، که یه پارامتر به نام `namespace` می‌گیره، داخل کلاسم یه Decorator تعریف کردم که کارش صرفا این هست که میگه کدوم تابع با کدوم namespace اجرا شدهحالا می‌خوایم از این decorator تو کد‌های قبل نسخه‌ی ۳.۹ استفاده کنیم@Test(namespace='Testing Environment').my_decorator def add(x, y): return x + y خط اول، از کلاسم یه Object ساختم و "Testing Environment" رو بهش به عنوان namespace دادم، در ادامه هم متود `my_decorator` رو ازش استفاده کردماما در صورتی که این کد رو اجرا کنم با خطای زیر مواجه میشمFile "/tmp/py3.9.py", line 11 @Test(namespace='Testing Environment').my_decorator ^SyntaxError: invalid syntaxتو نسخه‌های قبل ۳.۹، امکان استفاده از نقطه بعد از پرانتز به عنوان Decorator وجود نداشت، تو نسخه‌ی ۳.۹ این امکان اضافه شدهکدی که بالاتر نوشتم، روی پایتون ۳.۹ کار می‌کنهبرای این که روی نسخه‌های قبلی هم کار کنه، باید به این شکل نوشته بشهtest_env = Test(namespace='Testing Environment') @test_env.my_decorator def add(x, y): return x + yساخته شدن Object به صورت جدا انجام شد و از Decorator هم تونستیم استفاده کنیم? متود‌های جدید— PEP 616: string methods to remove prefixes and suffixes.۲تا متود خیلی خوب و جالب به `str` اضافه شده.`str.removeprefix`: حذف پیش‌وند از رشته`str.removesuffix`: حذف پس‌وند از رشتهبرای مثال یه سری آدرس سایت داریم و می‌خوایم همشون رو یه شکل بکنیم، اگر با www. شروع می‌شن، این www. رو ازشون حذف کنیم و اگر با / تموم میشن، / رو هم ازشون حذف کنیمaddresses = [&quotwww.google.com&quot, &quotbing.com/&quot, &quotduckduckgo.com&quot] normalized_addresses = [] for address in addresses: normalized_address = address.removeprefix('www.') # without www. normalized_address = normalized_address.removesuffix('/') # without trailing slash normalized_addresses.append(normalized_address)در نهایت اگر normalized_addresses رو `print` بگیریم، می‌بینیم که www. ها و / های بعد از آدرس رو حذف کرده!? کتاب‌خانه‌ی zoneinfo به صورت Standardبه نظر من، این یکی از خوشحال‌کننده‌ترین مواردی بود انجام شد، تو نسخه‌های قبلی نیاز بود از کتاب‌خونه‌هایی مثل `pytz` استفاده کنید تا بتونید اطلاعات Timezone های دیگه رو داشته باشیدتو نسخه‌ی ۳.۹، یه کتاب‌خونه‌ی پیش‌فرض و استاندارد به نام `zoneinfo` اضافه شده که این اطلاعات رو بهتون میده و دیگه نیاز ندارید چندتا کتاب‌خونه‌ی مختلف برای اطلاعات Timezoneهای مختلف نصب کنید.from zoneinfo import ZoneInfo from datetime import datetime, timedelta dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo(&quotAsia/Tehran&quot)) # Output as string: 2020-10-31 12:00:00+03:30 dt.tzname() # Output: &quot+0330&quotکلی تغییرات باحال و خفن دیگه وجود داره که اینجا پوشش نمی‌دمشون، اگر علاقه دارید، توصیه می‌کنم حتما و حتما Whats New in Python 3.9 رو داخل مستندات پایتون بررسی کنیدبهینه‌سازی‌های خیلی زیادی انجام شده، سرعت عمل‌کرد و کارایی تا حد زیادی بهبود پیدا کردهحتا یه PEP صرفا برای برنامه‌ی انتشار پایتون نوشته و تایید شدهطبق PEP 602، هر سال، ماه October یه نسخه‌ی پایدار از پایتون منتشر میشهبرای مثال سال آینده،یک‌ماه قبل‌تر از الآن پایتون ۳.۱۰ منتشر میشه و در موردش می‌نویسم :)PEP 602 - Python annual release cycle