آموزش duck typing در پایتون

December 2021

وقتی وارد اکوسیستم پایتون میشوید باید کدهای پایتونیک بنویسید. pythonic به مجموعه قواعدی گفته میشود که برنامه نویسان پایتون برای بهتر کد نوشتن پیشنهاد میدهند. در این ویدیو در رابطه با سه موضوع مهم صحبت خواهد شد که میتوانید با آنها کدهای پایتونیک بنویسید.

 

مفاهیمی که در این ویدیو بیان خواهد شد، عبارتند از:

 

بیایید جداگانه به هر سه این موارد نگاهی بیندازیم.

 

 

 #  مفهوم duck typing در پایتون

مفهوم duck typing به زمانی اشاره میکند که  نوع  اطلاعات ورودی اهمیت ندارد و فقط نیاز است که اطلاعات ورودی  ویژگی  خاصی را داشته باشند. در زمانی که از duck typing در کد خود استفاده میکنید نیازی نیست که نوع آبجکت ورودی را بررسی کنید. فقط وجود متد یا attribute خاصی را بررسی میکنید.

 

مثالی که میتوان از duck typing در پایتون زد، فانکشن ()len است. برای فانکشن len اهمیتی ندارد که چه نوع آبجکتی را میگیرد. تنها چیزی که اهمیت دارد، وجود متد __len__ است. هر آبجکتی که متد __len__ را در خود داشته باشد، میتواند به متد len ارسال شود در غیر اینصورت پیغام خطای TypeError خواهد داد.

 

به مثال زیر دقت کنید:

>>> len('amir')
4

>>> len([1, 'amir', 6])
3

 

متد len به طور کامل مفهوم duck typing را پیاده سازی کرده است. بدون اهمیت به نوع آبجکت، تعداد آیتم‌های درون آن را برمیگرداند.

 

اما مفهوم duck typing میتواند خطرناک باشد. اگر نتوانید به درستی تمام حالت‌های ممکن را کنترل کنید ممکن است در کدتان به مشکل بخورید. متد len نمیتواند روی آبجکت‌های عددی کار کند:

>>> len(373)

Traceback (most recent call last):
  File "/home/amir/Desktop/python/two.py", line 15, in <module>
    print(len(373))
TypeError: object of type 'int' has no len()

 

در اینجاست که باید قبل از استفاده، بررسی کنید که آیا ویژگی که به دنبال آن هستید در آن آبجکت وجود دارد یا نه. اگر وجود داشت که میتوانید ادامه دهید اگر وجود نداشت باید از ادامه عملیات جلوگیری کنید. برای این بررسی باید از ویژگی LBYL استفاده کنید. به بخش بعدی بروید.

 

 

 #  مفهوم LBYL در پایتون

مفهوم LBYL مخفف جمله "Look Before You Leap" است. به این معنی که، قبل از اینکه کاری انجام دهی، اول بررسی کن. این مفهوم توضیح میدهد که بهتر است قبل از انجام کاری بررسی کنید که آیا متد یا ویژگی خاصی که به دنبال آن هستید در آبجکت وجود دارد یا خیر.

 

همان مثال بخش قبل را ادامه میدهیم. حالا قبل از استفاده از متد len باید بررسی کنیم که آیا آبجکت ورودی دارای متد __len__ است یا خیر. به مثال زیر دقت کنید:

def check_len(obj):
	if hasattr(obj, '__len__'):
		print(len(obj))
	else:
		print('Sorry...')

 

در کد بالا یک فانکشن داریم که یک obj ورودی دارد. اگر این obj متد __len__ را با خود داشته باشد، آن را به متد len ارسال میکنیم در غیر اینصورت یک پیغام مناسب نشان میدهیم. در این کد ما از مفهوم LBYL استفاده میکنیم. قبل از اینکه روی obj کاری بکنیم، بررسی میکنیم که آیا ویژگی __len__ را دارد یا نه.

 

حالا بیایید از فانکشن بالا استفاده کنیم:

>>> check_len('amir')
4

>>> check_len([1, 'jack', 78])
3

>>> check_len(3435)
Sorry...

 

همانطور که میبیند دیگر کد ما هیچ استثنایی ایجاد نمیکند و در هر نوع آبجکتی به خوبی کار میکند.

 

اما باید بدانید که مفهوم LBYL آنچنان پایتونیک نیست و در اکوسیستم پایتون پیشنهاد میشود که از آن استفاده نکنید. به جای آن میتوانید از مفهوم بهتری با عنوان EAFP استفاده کنید.

 

 

 #  مفهوم EAFP در پایتون

مفهوم EAFP مخفف جمله "it’s easier to ask for forgiveness than permission" است. این مفهوم کاملا برعکس LBYL است. به این معنی که نیازی به بررسی نیست، اول کاری که میخوای رو انجام بده، اگر درست کار کرد که هیچی، اما اگر درست کار نکرد، معذرت خواهی بکن.

 

در ادامه مثال قبل، دیگر نیازی به بررسی وجود ویژگی نیست. ابتدا ویژگی را فراخوانی میکنیم اگر وجود داشت که کدمان به درستی کار خواهد کرد، در غیر اینصورت باید exception که رخ میدهد را کنترل کنیم.

 

مثال بالا را با استفاده از مفهوم EAFP بازنویسی میکنیم:

def check_len(obj):
	try:
		print(len(obj))
	except TypeError:
		print('Sorry...')

 

در کد جدید دیگر وجود متد __len__ را بررسی نمیکنیم. مستقما کد را اجرا میکنیم، در صورت بروز خطا، دوباره پیغام خطای مناسب را به کاربر نشان میدهیم.

 

در مثال جدید کد ما از دو نظر بهتر شده است:

  1. کد کوتاه‌تر شده پس خوانایی آن بیشتر شده.
  2. سرعت کد بیشتر شده چون دیگر نیازی به دسترسی به آبجکت و بررسی اضافی نداریم.

 

 

ارسال نظر

تلاش میکنم سوالات شما را در کمتر از یک روز پاسخ بدم

Mahdi

January 2022

فوق العاده

پاسخ به نظر


امیر محمد

December 2021

عالی بود

پاسخ به نظر