Vahid Masoumi
Vahid Masoumi
خواندن ۱ دقیقه·۶ سال پیش

ارسال متغیر با مقدار (Passing by value) در پایتون

دوس دارم از این به بعد چیزایی که به نظرم یکم جالب میاد رو بنویسم. زبون پایتون یکی از جذاب‌ترین زبون‌هاس و دونستن نکته‌های این زبون هم می‌تونه واسه کسایی که دوسش دارن جالب باشه. خب حالا که تا اینجا خوندید به نظر شمام پایتون دوس دارید :دی حالا که پایتون دوس دارید به نظرتون خروجی تیکه کد زیر چیه؟

mylist=[] for c in range(3): mylist.append(lambda x:print(x*c, end=',')) for f in mylist: f(True)

ممکنه تو نگاه اول به نظر بیاد که خروجی اینه:

Output: 0,1,2,

اما اینطور نیست! اگه براتون جالبه که بدونید دلیلش چیه، ادامه رو بخونید.




اول یه نکته کوچیک درباره True و False توی پایتون بگم. توی python3 مقادیر True و False به ترتیب ۱ و ۰ هستن پس ضرب True در هر عددی همون عدد رو می‌ده.

نکته‌ای که اینجا وجود داره این هست که ما توی اینجا تنها یه متغیر c داریم و تابع لامبدا هم قراره ضرب آرگومان ورودی‌اش با این متغیر c رو انجام بده اما این تابع لامبدا در اون لحظه صدا زده نشده که مقادیر اصلی بهش وصل بشه و در نتیجه تنها رفرنس متغیر c هست که توی این تابع باند میشه و تا زمانی که کال نشه ارزیابی نمی‌شه که مقدارش چی هست. با این تفاسیر، حلقه ما می‌رسه به آخر و تابع لامبدا رفرنس c آخرین حلقه رو برای تابع لامبدا در نظر می‌گیره که مقدار c آخر ۲ هست.

اگر مقدار رفرنس‌های متغیرها رو هم چاپ کنیم می‌تونیم این رو ببینیم:

mylist=[] for c in range(3): print("c: %s, ID(c): %s" % (c, id(c))) mylist.append(lambda x: print('Value: %s, ID(c): %s, ID(x): %s' % (x*c, id(c), id(x)))) for f in mylist: f(True)

که خروجی به این صورت هست:

c: 0, ID(c): 4304853792 c: 1, ID(c): 4304853824 c: 2, ID(c): 4304853856 <- Reference Value Value: 2, ID(c): 4304853856, ID(x): 4304466784 Value: 2, ID(c): 4304853856, ID(x): 4304466784 Value: 2, ID(c): 4304853856, ID(x): 4304466784

با استفاده از تابع ()id می‌تونین مقدار رفرنس متغیر‌ها رو ببینید. همونجوری که توی خروجی می‌بینید مقداری که داخل لامبدا فانکشن داره استفاده میشه مقدار آخرین رفرنس داخل لوپ یعنی ۲ هست به خاطر همین تمام خروجی‌ها ۲=۲*۱ شده.



خب حالا چیکار کنیم که مقدار c توی هر لوپ در نظر گرفته بشه و خروجی‌مون بشه:

Output: 0,1,2,

یه راهش اینه که c رو از طریق آرگومان پیش‌فرض (default argument) لامبدا ست کنیم که evaulte بشه و مقدار خودش پاس داده بشه:

mylist=[] for c in range(3): print("c: %s, ID(c): %s" % (c, id(c))) mylist.append(lambda x, c=c: print('Value: %s, ID(c): %s, ID(x): %s' % (x*c, id(c), id(x)))) for f in mylist: f(True)

که خروجی به این صورت می‌شه:

c: 0, ID(c): 4304853792 c: 1, ID(c): 4304853824 c: 2, ID(c): 4304853856 Value: 0, ID(c): 4304853792, ID(x): 4304466784 Value: 1, ID(c): 4304853824, ID(x): 4304466784 Value: 2, ID(c): 4304853856, ID(x): 4304466784

ایشالا که جذاب بوده باشه براتون و توی کد زدن‌هاتون در نظر بگیریدش.

برنامه‌نویسیارسال متغیر در پایتونپایتون
شاید از این پست‌ها خوشتان بیاید