توابع lambda و شیء گرایی در پایتون

توابع lambda و شیء گرایی در پایتون

lambda در پایتون چیست؟

تابع lambda در پایتون یک تابع anonymous (توابع بدون اسم) کوچک است که می تواند هر تعداد آرگومانی را گرفته اما باید تنها یک Expression داشته باشد. ساختار کلی تابع lambda در پایتون بدین شکل است:

lambda arguments : expression

برای مثال یک تابع lambda را در کد زیر می بینید که به عدد پاس داده شده (آرگومان) 10 واحد اضافه کرده و سپس نتیجه را print می کند:

x = lambda a: a + 10
print(x(5))

خروجی عدد 15 است.

مثال دیگر تابع lambda زیر است که دو آرگومان a و b را می گیرد سپس آن ها را در هم ضرب کرده و نتیجه را پرینت می کند:

x = lambda a, b: a * b
print(x(5, 6))

خروجی عدد 30 است.

ما می توانیم همینطور به تعداد این آرگومان ها اضافه کنیم به طور مثال:

x = lambda a, b, c: a + b + c
print(x(5, 6, 2))

در مثال بالا 3 آرگومان داریم که همه را با هم جمع کرده ایم اما می توانیم بی نهایت آرگومان نیز به آن اضافه کنیم. خروجی فعلی عدد 13 خواهد بود.

دلیل استفاده از توابع Lambda چیست؟

کاربرد اصلی توابع lambda درون توابع دیگر و به عنوان یک تابع anonymous است. فرض کنید تابعی دارید که یک آرگومان می گیرد که قرار است در عددی نامعلوم ضرب شود:

def myfunc(n):
  return lambda a : a * n

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

def myfunc(n):
  return lambda a : a * n

mydoubler = myfunc(2)

print(mydoubler(11))

خروجی عدد 22 است.

همچنین می توانید کاری کنید که این تابع همیشه اعداد را در 3 ضرب کند:

def myfunc(n):
  return lambda a : a * n

mytripler = myfunc(3)

print(mytripler(11))

خروجی 33 است.

و یا اینکه هر دو را در یک برنامه تعریف کنید تا از هر دو استفاده کنید:

def myfunc(n):
  return lambda a : a * n

mydoubler = myfunc(2)
mytripler = myfunc(3)

print(mydoubler(11)) 
print(mytripler(11))

خروجی:

22
33

بنابراین می توانید هر کاری با این توابع دوست داشتید انجام دهید. یادتان باشد که بهترین زمان استفاده از Lambda هنگامی است که برای مدت کوتاهی نیاز به یک تابع anonymous داشته باشیم.

آشنایی با کلاس ها و اشیاء

پایتون یک زبان برنامه نویسی شی گرا است و تقریبا همه چیز در پایتون شی محسوب می شود که دارای خصوصیات و متدهای خودش است. برای درک اشیا و کلاس ها می توانید این چنین تصور کنید:

کلاس یک نقشه برای شی است! به طور مثال یک نقشه ی خانه داریم و بر اساس این نقشه و اطلاعات آن، خانه (شی) را می سازیم. این نقشه دارای دستورالعمل هایی است (مانند «در را اینطور بساز» یا «حیاط را این رنگی کن» و …) که به آن ها متد می گوییم. از طرفی هر خانه خصوصیاتی دارد (مثلا رنگ دیوار ها، نوع سنگ فرش، اندازه ی اتاق ها و …) که به این ها «خصوصیت» یا property می گوییم. همچنین همانطور که می توانیم از یک نقشه صد ها خانه بسازیم، می توانیم از یک کلاس نیز صدها شی بسازیم. به عمل ساختن شی از یک کلاس instantiate کردن می گویند. instance یا نمونه‌ی یک کلاس، یعنی شی ای که از آن کلاس ساخته شده است.

ساخت شی و کلاس

برای ساخت یک کلاس باید از کلیدواژه ی class استفاده کنید:

class MyClass:
  x = 5

print(MyClass)

خروجی:

<class '__main__.MyClass'>

حالا برای ساخت یک شی از کلاس مورد نظر باید بدین شکل عمل کنیم:

class MyClass:
  x = 5

p1 = MyClass()
print(p1.x)

در واقع ابتدا یک کلاس ساخته ایم (MyClass) و سپس از نام کلاس به شکل فراخوانی یک تابع استفاده کرده ایم و شی p1 را ساخته ایم. در آخر هم مقدار  x (یک خصوصیت) را پرینت کرده ایم.

استفاده از تابع ()__init__

کلاس و شی ای که بالاتر ساخته ایم ساده ترین حالت شی و کلاس هستند و در برنامه نویسی پروژه های واقعی هیچ استفاده ای ندارند. برای آنکه معنای کلاس ها را درک کنیم باید تابع ()__init__ را بشناسیم. این تابع در تمام کلاس ها موجود است و هر زمان که شی ای از کلاسی ساخته می شود این تابع نیز اجرا خواهد شد. بنابراین می توانیم از آن برای مقدار دهی اولیه به خصوصیات (property) شی یا انجام عملیات های دیگر استفاده کنیم. به طور مثال در کد زیر کلاسی به نام Person داریم و از تابع ()__init__ استفاده کرده ایم تا به خصوصیات name و age مقدار اولیه بدهیم:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

p1 = Person("John", 36)

print(p1.name)
print(p1.age)

با این کار هر کسی که بخواهد از کلاس Person استفاده کند باید مقادیر مناسبی برای name و age آن شی انتخاب کند. در مورد self توضیح خواهیم داد.

متدها (method) در اشیاء

اشیاء می توانند متدهایی داشته باشند و به زبان ساده متدها توابعی هستند که مخصوص یک شی خاص می باشند. اگر بخواهیم در کلاس Person (مثال بالا) یک متد تعریف کنیم که پیام خوش آمد گویی خاصی را پرینت کند باید بگوییم:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def myfunc(self):
    print("Hello my name is " + self.name)

p1 = Person("John", 36)
p1.myfunc()

خروجی:

Hello my name is John

سوال: چرا با اینکه از سن john (همان 36 سال) استفاده ای نمی کنیم اما آن را به Person پاس داده ایم؟

پاسخ: تابع ()__init__ به صورت خودکار و به محض ساخته شدن شی از یک کلاس اجرا می شود (معادل constructor در زبان های دیگر) و از ما name و age را می خواهد. بنابراین اگر بخواهیم شی ای از این کلاس بسازیم باید این مقادیر را به آن پاس بدهیم تا خصوصیات اجباری شی تعیین شود.

پارامتر self چیست؟

self به instance (نمونه) ی فعلی کلاس اشاره دارد بنابراین معادل this در زبان های دیگر است. همچنین برای دسترسی به متغیر های درون کلاس کاربرد دارد. به زبان ساده تر زمانی که از self استفاده می کنیم، می گوییم منظورمان همین کلاس و همین شی فعلی است. البته شما می توانید به جای self از هر نام دیگری استفاده کنید، نکته ی مهم این است که اولین پارامتر ورودی در توابع درون کلاس باشد. به طور مثال در کد زیر از کلمات mysillyobject و abc به جای self استفاده کرده ایم:

class Person:
  def __init__(mysillyobject, name, age):
    mysillyobject.name = name
    mysillyobject.age = age

  def myfunc(abc):
    print("Hello my name is " + abc.name)

p1 = Person("John", 36)
p1.myfunc()

خروجی:

Hello my name is John

ویرایش یا حذف خصوصیات (property) شی

برای تغییر خصوصیات یک شی می توانید به شکل زیر عمل کنید:

p1.age = 40

بنابراین در یک مثال عملی می توان گفت:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def myfunc(self):
    print("Hello my name is " + self.name)

p1 = Person("John", 36)

p1.age = 40

print(p1.age)

خروجی عدد 40 خواهد بود.

اما برای حذف خصوصیات یک شی تنها کافی است که از کلیدواژه ی del استفاده کنید:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def myfunc(self):
    print("Hello my name is " + self.name)

p1 = Person("John", 36)

del p1.age

print(p1.age)

خروجی خطای زیر خواهد بود چرا که چنین خصوصیتی دیگر وجود ندارد:

AttributeError: 'Person' object has no attribute 'age'

توجه داشته باشید که می توانید از کلیدواژه ی del برای حذف یک شی کامل نیز استفاده کنید:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def myfunc(self):
    print("Hello my name is " + self.name)

p1 = Person("John", 36)

del p1

print(p1)

خروجی خطای زیر خواهد بود:

NameError: 'p1' is not defined

بحث شی گرایی بحث شیرینی است، شما می توانید با تمرین بیشتر بر این بحث تسلط پیدا کرده و وارد دنیای جدیدی شوید! در قسمت بعد در رابطه با وراثت (inheritance) صحبت خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری از مقدماتی تا پیشرفته با پایتون توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.