نسخهی پایدار پایتون ۳.۹، تو تاریخ ۵ اکتبر منتشر شد، تو این پست یه مرور کوتاه و کلی روی تغییرات جدیدی که روی پایتون ۳.۹ اعمال شده با هم انجام میدیم.
— PEP 584: Union operators added to `dict`
— 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` اضافه شده.
برای مثال یه سری آدرس سایت داریم و میخوایم همشون رو یه شکل بکنیم، اگر با www. شروع میشن، این www. رو ازشون حذف کنیم و اگر با / تموم میشن، / رو هم ازشون حذف کنیم
addresses = ["www.google.com", "bing.com/", "duckduckgo.com"] 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. ها و / های بعد از آدرس رو حذف کرده!
به نظر من، این یکی از خوشحالکنندهترین مواردی بود انجام شد، تو نسخههای قبلی نیاز بود از کتابخونههایی مثل `pytz` استفاده کنید تا بتونید اطلاعات Timezone های دیگه رو داشته باشید
تو نسخهی ۳.۹، یه کتابخونهی پیشفرض و استاندارد به نام `zoneinfo` اضافه شده که این اطلاعات رو بهتون میده و دیگه نیاز ندارید چندتا کتابخونهی مختلف برای اطلاعات Timezoneهای مختلف نصب کنید.
from zoneinfo import ZoneInfo from datetime import datetime, timedelta dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("Asia/Tehran")) # Output as string: 2020-10-31 12:00:00+03:30 dt.tzname() # Output: "+0330"
کلی تغییرات باحال و خفن دیگه وجود داره که اینجا پوشش نمیدمشون، اگر علاقه دارید، توصیه میکنم حتما و حتما Whats New in Python 3.9 رو داخل مستندات پایتون بررسی کنید
بهینهسازیهای خیلی زیادی انجام شده، سرعت عملکرد و کارایی تا حد زیادی بهبود پیدا کرده
حتا یه PEP صرفا برای برنامهی انتشار پایتون نوشته و تایید شده
طبق PEP 602، هر سال، ماه October یه نسخهی پایدار از پایتون منتشر میشه
برای مثال سال آینده،یکماه قبلتر از الآن پایتون ۳.۱۰ منتشر میشه و در موردش مینویسم :)