انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


توزیع گنو/لینوکس اوبونتو ۲۰ ساله شد 🎉

نویسنده موضوع: [پایتون] - متغیر(؟) self وتابع __init__ چی هستند و چیکار می کنند؟ (حل شد)  (دفعات بازدید: 9088 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین سالار مقدم

  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 2074
  • جنسیت : پسر
  • هر چقدر بدونی بازم کمه.
    • سالار مقدم
سوال واضحه، کلی سرچ انگلیسی کردم ولی هیچی متوجه نشدم ...
برای کسی توضیح بدید که (تقریبا) از شی گرایی هیچی نمی دونه.
مثلا کد زیر رو که میزنم ارور زیر رو میده:
1 class test:
2     def tes(self, a, b):
3         self.a = a
4         self.b = b
5 x = test
6 x.tes(2, 3)
7 print(x.a, x.b) 
Traceback (most recent call last):
  File "./learn.py", line 6, in <module>
    x.tes(2, 3)
TypeError: tes() missing 1 required positional argument: 'b'

shell returned 1

Press ENTER or type command to continue

یا مثلا نمیدونم اصلا کد زیر چیه:
    def __init__(self):
لطفا با حوصله و کامل جواب بدید
« آخرین ویرایش: 21 آذر 1392، 07:31 ب‌ظ توسط سالار مقدم »

آفلاین امید توانا

  • Hero Member
  • *
  • ارسال: 981
  • جنسیت : پسر
سوال واضحه، کلی سرچ انگلیسی کردم ولی هیچی متوجه نشدم ...
برای کسی توضیح بدید که (تقریبا) از شی گرایی هیچی نمی دونه.
مثلا کد زیر رو که میزنم ارور زیر رو میده:
1 class test:
2     def tes(self, a, b):
3         self.a = a
4         self.b = b
5 x = test
6 x.tes(2, 3)
7 print(x.a, x.b) 
Traceback (most recent call last):
  File "./learn.py", line 6, in <module>
    x.tes(2, 3)
TypeError: tes() missing 1 required positional argument: 'b'

shell returned 1

Press ENTER or type command to continue

یا مثلا نمیدونم اصلا کد زیر چیه:
    def __init__(self):
لطفا با حوصله و کامل جواب بدید
x = test رو به
x = test()تبدیل کنید تا درست بشه.
def __init__(self)سازنده (constructor)شیئ است که اگر صریح معرفی نشه خود زبان یکی به صورت تهی درست می‌کنه، یعنی
def __init__(self):کار سازنده از اسمش مشخصه، یک نمونه از شیئ رو می‌سازه. مثلن در مثال زیر
class Rectangle:
def __init__(self, width = 2, height = 3):
self._width = width
self._height = height

def set_sides(self, width, height):
self._width = width
self._height = height

def get_area(self):
return self._width * self._height

rect1 = Rectangle()
print("The area of rect1 is ", rect1.get_area())
rect1.set_sides(4, 5)
print("The area of rect1 is ", rect1.get_area())

rect2 = Rectangle(5, 6)
print("The area of rect2 is ", rect2.get_area())
خروجی اینه
The area of rect1 is  6
The area of rect1 is  20
The area of rect2 is  30
تا سازنده اجرا نشه، شیئ ساخته نمی‌شه. در حقیقت rect1 = Rectangle() باعث می‌شه سازندهٔ __init__ با مقدارهای پیش‌نشان ۲ و ۳ اجرا بشه. اگر __init__ رو معرفی نکنید خود زبان یکی به صورت خالی درست می‌کنه ولی همچنان شما باید در هنگام ساختن شیئ، به صورت x = test()فراخوانیش کنید.

self معادل this در زبان C++ است که اشاره‌ای به خود شیئ دارد. ‌هر رویه در یک شیئ باید self رو به عنوان اولین آرگومان داشته باشه (واقعا نمی‌دونم چرا! C++ این‌طور نیست)
« آخرین ویرایش: 21 آذر 1392، 01:59 ب‌ظ توسط امید توانا »

آفلاین !

  • High Sr. Member
  • *
  • ارسال: 586
  • جنسیت : پسر
  • Don't Panic!
    • مانیتورینگ سایت
خب اول راجع به  __init__ :

در هر کلاسی یک تابعی به نام  __init__ تعریف میشه که سازنده یا constructor اون کلاس هست.خب این یعنی چی؟ این یعنی اینکه موقعی که یک شی از اون کلاس میسازید مقادیر و آرگومانهای اولیه اش رو تعریف میکنید و self هم (عین this تو جاوا) به مقادیری درون کلاس اشاره میکنه.

یکخورده نامفهوم بود بزار با مثال بگم.

فرض کن میخوایم یک کلاسی بسازیم که دوتا عدد رو باه جمع کنه و مجموعشون رو بهمون بده.یک کلاس میسازیم به اسم sum :

class sum:

خب مقادیر پیش فرض رو به کلاس با تعریف تابع __init__مشخص میکنیم :

class sum:
     def __init__(self,a,b):
      self.a = a
      self.b = b

خب از کلاسی که ساختیم یک نمونه شی میسازیم که بقیه ی توضیحات رو عارض بشم :


x = sum(5,10)
الان یک شی ساختیم به اسم x از کلاس sum که دوتا مقدار بهش دادیم که اولی تو a و دومی تو b قرار میگیره و self هم تو تعریف کلاس نادیده گرفته میشه و فقط آرگومانی ضروری برای داخل کلاسه و آرگومانهای بعدی از تابع __init__ آرگومانهایی هستند که موقع تریف اولیه تابع مقدار دهی میشند مثل مثالی که گفتم.

حالا یک متد دیگه تو کلاس میسازیم به اسم printSum که جمع دو تا مقداری رو که موقع تعریف کلاس داده بودیم رو روی صفحه چاپ کنه :

class sum:
     def __init__(self,a,b):
      self.a = a
      self.b = b

     def printSum(self):
      self.sum = self.a + self.b
      print(self.sum)


یک نگاهی به تابع بالا بنداز، همیشه آرگومان اول self هست و مادامیکه اون شی زندست (مثلا شی x تو اینجا) مقادیر self ذخیره شدن توش و با فراخوانی هر متد از اون کلاس همچنان قابل فراخانی اند.

حالا از متد بالا تو شی x استفاده میکنیم :
x.printSum()

و متد پرینت سام اجرا میشه و مقادیری که موقع تعریف شی به کلاس داده بودیم حالا جمعشون رو فراخوانی و چاپ کردیم..

اینم کد کل برنامه ای که نوشتیم :

class sum:
     def __init__(self,a,b):
      self.a = a
      self.b = b

     def printSum(self):
      self.sum = self.a + self.b
      print(self.sum)
x = sum(5,10)
x.printSum()

I just felt like running

Altern AI Directory --- GitHub

آفلاین سالار مقدم

  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 2074
  • جنسیت : پسر
  • هر چقدر بدونی بازم کمه.
    • سالار مقدم
ممنون دوستان خیلی خوب متوجه شدم :)
مسئله فوق العاده نا مفهومی بود ولی خوشبختانه تو سی پلاس پلاس با سازنده ها کار کرده بودم و متوجه شدم، حلا چند تا سوال دیگه:
x = test رو به
x = test()تبدیل کنید تا درست بشه.
چرا؟ اینجا که سازنده ای تعریف نکردیم چرا باید به کلاس لیست آرگومان تهی بدیم؟ مگه سازنده فقط __init__ نیست؟
الان ما self رو چی صدا کنیم؟ متغیر؟ اشاره گر به متغیر های ذخیره شده ی یک شی؟
با توضیحات داده شده متوجه شدیم که self داده های یک شی رو ذخیره می کنه، بنابر این ما self رو باید تو همه ی توابعمون به کار ببریم؟همه ی متغیر هایی که توسط سازنده اعلان می کنیم باید قبلش self.* داشته باشه؟ به جز این چه کاربردی داره؟ به جز توابع کجاها استفاده میشه؟ خارج از کلاس ها هم استفاده میشه؟
زمانی که self._a = a رو تعریف کردیم تو خود تابع کلاس می تونیم از متغیر _a استفاده کنیم؟ خارج از تابع داخل کلاس چی؟ اگه نه چرا؟(شرمنده دسترسی به پایتون ندارم برای همین می پرسم)
در ادامه:
http://forum.ubuntu.ir/index.php/topic,82032.new.html
http://forum.ubuntu.ir/index.php/topic,81407.msg679867.html
ممنون از امید و مخصوصا داریوش بخاطر توضیحات کاملتون
« آخرین ویرایش: 21 آذر 1392، 02:56 ب‌ظ توسط سالار مقدم »

آفلاین سالار مقدم

  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 2074
  • جنسیت : پسر
  • هر چقدر بدونی بازم کمه.
    • سالار مقدم
اینو یادم رفت بپرسم، ما یه کشنده هم داشتیم تو سی پلاس پلاس، اینتو هم هست؟ به جز این دو تا قابلیت دیگه ای تو شی های پایتون هست؟

آفلاین امید توانا

  • Hero Member
  • *
  • ارسال: 981
  • جنسیت : پسر
ممنون دوستان خیلی خوب متوجه شدم :)
مسئله فوق العاده نا مفهومی بود ولی خوشبختانه تو سی پلاس پلاس با سازنده ها کار کرده بودم و متوجه شدم، حلا چند تا سوال دیگه:
x = test رو به
x = test()تبدیل کنید تا درست بشه.
چرا؟ اینجا که سازنده ای تعریف نکردیم چرا باید به کلاس لیست آرگومان تهی بدیم؟ مگه سازنده فقط __init__ نیست؟
الان ما self رو چی صدا کنیم؟ متغیر؟ اشاره گر به متغیر های ذخیره شده ی یک شی؟
با توضیحات داده شده متوجه شدیم که self داده های یک شی رو ذخیره می کنه، بنابر این ما self رو باید تو همه ی توابعمون به کار ببریم؟همه ی متغیر هایی که توسط سازنده اعلان می کنیم باید قبلش self.* داشته باشه؟ به جز این چه کاربردی داره؟ به جز توابع کجاها استفاده میشه؟ خارج از کلاس ها هم استفاده میشه؟
زمانی که self._a = a رو تعریف کردیم تو خود تابع کلاس می تونیم از متغیر _a استفاده کنیم؟ خارج از تابع داخل کلاس چی؟ اگه نه چرا؟(شرمنده دسترسی به پایتون ندارم برای همین می پرسم)
در ادامه:
http://forum.ubuntu.ir/index.php/topic,82032.new.html
http://forum.ubuntu.ir/index.php/topic,81407.msg679867.html
ممنون از امید و مخصوصا داریوش بخاطر توضیحات کاملتون
گفتم که اگه سازنده تعریف نکنید خود زبان یکی تهی تهیه می‌کنه و به هرحال در زمان ساخت اجرا می‌شه.self داده‌ها رو ذخیره نمی‌کنه، self خود شیئ است. در پایتون متغیرهای یک کلاس هیج‌گاه به طور مستقیم اشاره نمی‌شن. در خارج از کلاس به شکل class_instance.attribute اشاره می‌شن و داخل خود کلاس به شکل self.attribute اشاره می‌شن.‌در مثال شما، متغیر a از کلاس test در خارج از کلاس به شکل x.a اشاره می‌شه و در داخل خود کلاس به شکل self.a.
« آخرین ویرایش: 21 آذر 1392، 03:10 ب‌ظ توسط امید توانا »