عملگر walrus در پایتون =: (walrus operator)

با سلام. توی این پست می خوام شما رو با یکی از از عملگر های جدید پایتون به نام walrus (معادل فارسیشو نمی دونم ولی تو دیکشنری که زدم، میگفت میشه شیرماهی) که در نسخه 3.8 به آن اضافه شده آشنا کنم. این عملگر به این شکل نشون داده می شه ( =: ).همه ما برخی اوقات با همچین موقعیت هایی مواجه میشیمm1 = p1.match(data) m2 = p2.match(data) if m1: pass elif m2: passتوی این برنامه، سعی می کنیم دو الگو رو روی data تست کنیم، هر کدوم که match شد کار های مربوط به اون رو انجام میدیم اما این برنامه زیاد بهینه نیست. چون ما دو تا الگو رو یک جا تست می کنیم و این مرحله برنامه رو کمی کند می کنه. اگه الگوی اول match بشه، دومی بلااستفاده می مونه. در نتیجه ما از m2 هیچ استفاده خاصی نکردیم و فقط زمان هدر دادیم. شاید بهتر بود که این برنامه رو اینطور پیاده سازی کنیمm1 = p1.match(data) if m1: pass else: m2 = p1.match(data) if m2: pass در این برنامه در صورتی که الگوی اول match بشه، دیگه ما سراغ دومی نمیریم اما اگه نشد، اونوقت ما دومی رو تست می کنیم. شاید متوجه شده باشید که خیلی ساختار برنامه پیچیده شد. کد ها خوانایی کمتری نسبت به قبل دارند. و این دقیقا همون مشکلیه که می خواهیم با walrus حلش کنیم. با استفاده از این عملگر جدید می تونیم کد رو طوری بنویسیم که از اولش هم خوانا تر و سریع تر باشهif m1 := p1.match(data): pass elif m2 := p2.match(data): passنیازی به توضیح نیست، به راستی این است خوانایی پایتون!اول از همه بزارید چند تا مثال دیگه برای استفاده از این عملگر بزنم که با ماهیت استفاده اش آشنا بشید بعد همه ی موارد استفاده و نحوه استفاده از این عملگر تو هر کدوم رو برسی می کنیم. حالا کد زیر رو در نظر بگیرید.variable = &quotvalue&quot print (variable)اما حالا پایتون 3.8 به شما این امکان رو میده تا این دو خط کد رو به یک خط کد تبدیل کنیدprint (variable := &quotvalue&quot)اگر این خط کد رو اجرا کنید، value چاپ میشه و مقدارش هم توی متغیر variable ذخیره میشه. بعد ها می تونید از همین variable دوباره استفاده کنید و نیازی به دوباره محاسبه کردن نیست. ( دقیقا همون کاری که در مثال قبلی انجام دادیم)مثال بعدی: فرض کنید که برنامه ای دارید که آیتم هایی رو از کاربر به عنوان ورودی میگیره و اون رو به یک لیست (سبد خرید کاربر) اضافه می کنه. و وقتی که کاربر کلمه Q رو وارد می کنه، گرفتن ورودی رو متوقف می کنه.shopping_cart = [] # initialize the list while True: item = input (&quotenter an item to add: &quot) if item == &quotQ&quot: break shopping_cart.append(item) # the rest of code ...خوب حالا این کد رو میشه اینطوری نوشت:shopping_cart = [] while (current := input(&quotenter an item to add: &quot)) != &quotQ&quot: shopping_cart.append(current)خیلی بهتر شد مگه نه؟دقیقا چیکار می کنه:خوب اگه دقیقا می خواید از کارش سر دربیارید، خیلی ساده است، ترمینالتون رو باز کنید و وارد کنسول پایتون بشید. حالا این کد رو اجرا کنید>>>(a:=10) out: 10 >>>همین که این کد رو اجرا کنید میبینید که 10 رو به عنوان مقدار برگشتی دارید. یعنی اینکه این عبارت هم در a ذخیره می کنه و هم مقدارش رو بر میگردونه پس ما می تونیم از مقدار برگشتی به عنوان ورودی توابع و ... استفاده کنیم و اگه دوباره نیاز به استفاده ازش داشتیم، به راحتی با استفاده از a به مقداری که قبلا حساب شده دسترسی داشته باشیم.به طور کلی هر جا از این استفاده کنید هیچ اتفاق خاصی نمی افته به غیر از اینکه اون مقدار توی متغیر گفته شده (که در سمت چپ =: قرار داره) ذخیره میشهمثلا:def function(arg): return arg * 2 function( a:=10 ) def function2(arg, kwarg): # the rest of code goes here ... function2(a:=10, kwarg = (b:=20))در اینجا هیچ اتفاق خاصی نمی افته به غیر از اینکه مقادیر، هم به عنوان ورودی به تابع داده میشه و هم اینکه در یک متغیر که نامش قبلا داده شده (در سمت چپ =: قرار داره) ذخیره میشه. به غیر از این، همه چیز مثل قبل کار میکنه.بعضی اوقات برخی از مقادیری که استفاده می کنیم حساب کردنشون سخته و برای اینکه برنامه از اینی که هست کند تر نشه باید فقط یک بار حسابش کنیم وگر نه دوبرابر برنامه مان کند تر میشه.یکی از مهم ترین استفاده های این عملگر برای جلوگیری از این طور موقعیت هاستنحوه نگارش (syntax):شما می تونید توی خیلی از عبارت های پایتون از =: استفاده کنید، نحوه استفاده اش اکثرا به این شکله:(identifier := expr)به طوری که identifier می تونه اسم یک متغیر باشه مثلا a، و expr هم می تونه هر گونه expression پایتون به غیر از tuple بدون پرانتز باشد. هر کجا که expression داشته باشید می تونید از =: استفاده کنید. مثلا:func( another_func(10, 20), 45) - 35این یک expression محسوب میشه (هر کدی که منجر به تولید خروجی بشه، expression محسوب میشه، expression ها تقریبا همه جا وجود دارند)خیلی خوب این هم از نحوه استفاده اش در موقعیت های مختلف:# conditional statements if identifier := f(x) : pass #something # using with while statements while chunck := file.read(1024): socket.send(chunck) # reuse a value which is expensive to compute numbers =[ (y:=f(x)) , y ** 2, y ** 3] # create a subsequence by filtering out some items new_numbers = [ y for x in numbers if (y:= SomeFilter(x)) is not None ]در برخی موارد می تونید از =: بدون پرانتز اطرافش استفاده کنید، مثل عبارت های شرطی، یا حلقه while اما برخی اوقات باید بین پرانتز قرارش بدید که در ادامه توضیح میدم. استفاده از =: در قسمت top level کد (قسمت اصلی کد، بدون اینکه عضوی از یک statement باشه) بدون استفاده از پرانتز اشتباهه>>> a := 10 # invalid >>> (a := 10) # validهمچنین استفاده از این عبارات در سمت راست یک عبارت بدون پرانتز ممنوعهc = a := 10 # completely invalid c = ( a := 10) # valid but not so usefulاستفاده از این عبارات موقع اختصاص مقادیر به توابع به صورت کلید/مقدار (key/value)، یا همون keyword argument بدون استفاده از پرانتز ممنوعهFunction(kwarg = c:=10) # invalid Function(kwarg = (c:=10)) # validاستفاده از این عبارات هنگام تعیین مقادیر پیشفرض برای پارامتر های توابع، باز هم بدون استفاده از پرانتز ممنوعهdef Function( argument = c := &quotdefault value&quot): pass # invalid def Function( argument = ( c := &quotdefault value&quot )): pass # validاستفاده از این عبارات به عنوان annotation ، بدون پرانتز ممنوعهdef s( a: c:=10 = 20): pass # invalid def s( a: (c:=10) = 20): pass #validاستفاده از این عبارات در توابعی که به صورت lambda تعریف شده اند، بدون پرانتز اشتباهه(lambda: x := 1) # INVALID lambda: (x := 1) # Valid, but unlikely to be useful (x := lambda: 1) # Valid lambda line: (m := re.match(pattern, line)) and m.group(1) # Validهنگام استفاده از این عبارت در fstring ها باید از پرانتز استفاده شودf&quot{(x:=2)}&quot # validاین عبارت درسته و مقدار 2 رو در x ذخیره می کنهx = &quotHello&quot f&quot{x:=10}&quot # validاین عبارت هم از لحاظ symtax درسته اما = رو به formatter میده و نتیجه اونطوری که ما می خواهیم نیست، ارور میگیریم!خوب، دونستن اینها تا به اینجا کافیه و حالا می تونید از این عملگر در برنامه های پایتونی تون استفاده کنید.ولی اگر خیلی دوست دارید راجب این عملگر اطلاعات بیشتری کسب کنید، به منبع این مطلب یعنی pep 572 سری بزنید.