PDA

View Full Version : ضرورت استفاده از کلاس ؟



arefenayat
سه شنبه 28 بهمن 1393, 08:54 صبح
سلام دوستان من یه تازه کار تو پایتون هستم ، قبلاً php کار کرده بودم ولی هیچ وقت با کلاس کار نکرده بودم و همیشه ازشون خوف داشتم ولی الان با پایتون دارم رو کلاس ها کار میکنم ولی نمیفهمم واقعاً استفاده از کلاس چه فایده و ضرورتی داره ؟
من دارم آموزشم رو با کتاب Headfirst جلو می برم ، مثلاً تو یکی از قسمت ها نوشته که این کلاس میتونه به هر نفر یک شی اختصاص بده

class Athlete:
def __init__(self, a_name, a_dob=None, a_times=[]):
self.name = a_name
self.dob = a_dob
self.times = a_times
و درست هم کار میکنه ولی نمیفهمم چه ضرورتی هست که ما بیایم برای این کار از کلاس استفاده کنیم در حالی که من همین کد رو با تابع نوشتم و کار می کرد

def cre(names,familys):
cre.name=names
cre.family=familys
return(cre.name,cre.family)
james=cre('ali','sadeghi')
ali=cre('ali','dabagh')

print(james)
print(ali)
print(type(ali))



لطفاً دوستان راهنمایی کنند چون خیلی گیج شدم

n.nowroozi
سه شنبه 28 بهمن 1393, 11:28 صبح
مهمترین چیزهایی که شما با این حرکت از دست دادید اینهاست:

ارث بری
امکان تعریف متد در داخل کلاس
امکان دسترسی به داده های هر instance از کلاس
...

arefenayat
سه شنبه 28 بهمن 1393, 12:10 عصر
مهمترین چیزهایی که شما با این حرکت از دست دادید اینهاست:

ارث بری
امکان تعریف متد در داخل کلاس
امکان دسترسی به داده های هر instance از کلاس
...



ممنون ولی خیلی کلی گفتید من که نفهمیدم (زیر دیپلم) :لبخندساده:
کلاً اگر میشه یه توضیح خوبی بدین ببینم این کلاس اصلاً به چه درد میخوره ؟ مهمتر از همه اینه من نمیدونم چه زمانی باید از کلاس استفاده کنم

راستی یه سوال دیگه


__init__

__call__
کاربرد اینا چی هست ؟؟؟؟

n.nowroozi
سه شنبه 28 بهمن 1393, 13:23 عصر
جواب سوالت رو توی این لینک (http://stackoverflow.com/a/9663601) میتونی ببینی .

فرض کن یه سری داده راجع وسایل حمل و نقل عمومی داری که میخوای توی یه دیتابیس ذخیره کنی.. یه کلاس پدر داری که توش ویژگیهایی عمومی وسایل نقلیه رو داری.. مثلا سال ساخت تعداد افرادی که میتونه جابجا کنه با سرعت جابجایی.. تو مرحله بعد میای اینهارو میشکنی به چند نوع داده مختلف مثل هواپیما ماشین و کشتی.. توی این مرحله واسه هرکدوم از اینها یه کلاس تعریف میکنی که توش ويژگیهای منحصر به فرد اون وسیله توش هست. مثلا کلاس ماشین شامل دارا بودن فرمان هیدرولیک و آپشنهای دیگه ماشینه و برای هواپیما و کشتی هم همینطور.. مزیت کلاس اینجا اینه که دیگه نیازی نیست شما ويژگیهای عام رو که در کلاس پدر تعریف شده مثل تعداد سر نشین و سال ساخت رو ذکر کنی فقط کافیه ارث بری کنی .. زمانی که ارث بری رو انجام میدی هر ويژگی ای پدر داشته باشه فرزند هم داره.. حالا این ساده ترین مثال از ارث بری بود که هرچه برنامت بزرگتر بشه این نیازرو بیشتر احساس میکنی.

arefenayat
سه شنبه 28 بهمن 1393, 20:57 عصر
جواب سوالت رو توی این لینک (http://stackoverflow.com/a/9663601) میتونی ببینی .

فرض کن یه سری داده راجع وسایل حمل و نقل عمومی داری که میخوای توی یه دیتابیس ذخیره کنی.. یه کلاس پدر داری که توش ویژگیهایی عمومی وسایل نقلیه رو داری.. مثلا سال ساخت تعداد افرادی که میتونه جابجا کنه با سرعت جابجایی.. تو مرحله بعد میای اینهارو میشکنی به چند نوع داده مختلف مثل هواپیما ماشین و کشتی.. توی این مرحله واسه هرکدوم از اینها یه کلاس تعریف میکنی که توش ويژگیهای منحصر به فرد اون وسیله توش هست. مثلا کلاس ماشین شامل دارا بودن فرمان هیدرولیک و آپشنهای دیگه ماشینه و برای هواپیما و کشتی هم همینطور.. مزیت کلاس اینجا اینه که دیگه نیازی نیست شما ويژگیهای عام رو که در کلاس پدر تعریف شده مثل تعداد سر نشین و سال ساخت رو ذکر کنی فقط کافیه ارث بری کنی .. زمانی که ارث بری رو انجام میدی هر ويژگی ای پدر داشته باشه فرزند هم داره.. حالا این ساده ترین مثال از ارث بری بود که هرچه برنامت بزرگتر بشه این نیازرو بیشتر احساس میکنی.

ممنون ، منظورتون رو متوجه شدم
فقط اگر میشه خودتون __init__ و __call__ رو توضیح بدید چون چیزی از اون لینک متوجه نشدم .
و یه مورد دیگه اینکه من توی بعضی برنامه ها می بینم که کلاس ساخته اند ولی توی کلاس از __init__ و __call__ استفاده نکرده اند . دلیلش چیه ؟ کلاً چه زمانی باید از اینا استفاده کرد

n.nowroozi
چهارشنبه 29 بهمن 1393, 08:02 صبح
همونطور که توی لینک گفته:
حالت init وقتی اجرا میشه که شما یک شئ جدید از اون کلاس بسازید یا میخواهید موقع ساخت شی چیزی پاس بدید.

class foo: def __init__(self, a, b, c):
# ...


x = foo(1, 2, 3) # __init__
ولی call بعد از اینکه شما object رو ساختید به شکل زیر قابل صدا کردنه:

class foo: def __call__(self, a, b, c):
# ...


x = foo()
x(1, 2, 3) # __call__

بر حسب نیازه قطعا! خیلی جاها شما نیاز دارید در ابتدا یک سری داده به کلاستون بدید و خیلی جاها این نیاز رو ندارید.

arefenayat
چهارشنبه 29 بهمن 1393, 08:58 صبح
همونطور که توی لینک گفته:
حالت init وقتی اجرا میشه که شما یک شئ جدید از اون کلاس بسازید یا میخواهید موقع ساخت شی چیزی پاس بدید.

class foo: def __init__(self, a, b, c):
# ...


x = foo(1, 2, 3) # __init__
ولی call بعد از اینکه شما object رو ساختید به شکل زیر قابل صدا کردنه:

class foo: def __call__(self, a, b, c):
# ...


x = foo()
x(1, 2, 3) # __call__

بر حسب نیازه قطعا! خیلی جاها شما نیاز دارید در ابتدا یک سری داده به کلاستون بدید و خیلی جاها این نیاز رو ندارید.

یعنی اگر من توی کلاسم از __init__ استفاده نکنم و مستقیماً برم سر __call__ بدون ایجاد یک شی اون رو call میکنم ؟

n.nowroozi
چهارشنبه 29 بهمن 1393, 11:36 صبح
یعنی اگر من توی کلاسم از __init__ استفاده نکنم و مستقیماً برم سر __call__ بدون ایجاد یک شی اون رو call میکنم ؟
نه بعد از اینکه شئ رو ایجادش کردید میتونید صداش کنید.
بزار اینجوری بگم هر موقع یک شئ ایجاد بشه حتما init اجرا میشه. اما call موقع ایجاد شئ صدا نمیشه بلکه زمانی اجرا میشه که شما شئ ای که قبلا ساختید رو صدا کنید.

arefenayat
چهارشنبه 29 بهمن 1393, 12:45 عصر
نه بعد از اینکه شئ رو ایجادش کردید میتونید صداش کنید.
بزار اینجوری بگم هر موقع یک شئ ایجاد بشه حتما init اجرا میشه. اما call موقع ایجاد شئ صدا نمیشه بلکه زمانی اجرا میشه که شما شئ ای که قبلا ساختید رو صدا کنید.
پس در اصل کار init این هست که شی رو توی حافظه بسازه و کار call این هست که دستوراتی که توی شی قرار دارند رو اجرا کنه درسته ؟؟؟
یه سوال دیگه فرض کند من کلاس زیر رو دارم
class car():
pass


چه تفاوتی هست بین دوتا کد پایین


t=car()
t=car
منظورم استفاده از پرانتز هست ؟ در حالی که من با هر دوتای اینها نتیجه یکسانی می گیرم .

n.nowroozi
چهارشنبه 29 بهمن 1393, 13:17 عصر
پس در اصل کار init این هست که شی رو توی حافظه بسازه و کار call این هست که دستوراتی که توی شی قرار دارند رو اجرا کنه درسته ؟؟؟

نه شما در هر صورت وقتی یه شئ ایجاد میکنید توی حافظه میشینه! init فقط مزیتش اینه بلافاصله پس از ایجاد شئ اجرا میشه


در مورد سوال دوم هم شما یک شئ از کلاس car ساختید اما دومی شئ نساختید بلکه گفتید که t هم نمایانگر کلاس car هست.

arefenayat
چهارشنبه 29 بهمن 1393, 13:35 عصر
نه شما در هر صورت وقتی یه شئ ایجاد میکنید توی حافظه میشینه! init فقط مزیتش اینه بلافاصله پس از ایجاد شئ اجرا میشه


در مورد سوال دوم هم شما یک شئ از کلاس car ساختید اما دومی شئ نساختید بلکه گفتید که t هم نمایانگر کلاس car هست.
خوب با این تفاسیر بود و نبود init چه تفاوتی داره ؟ کلاً به چه درد میخوره ؟ چه زمانی ازش باید استفاده کرد ؟
واقعاً ممنون
فقط یه سوال دیگه ، همین جریان برای تعریف کلاس هم وجود داره ، یعنی من میتونم کلاس رو با پرانتز و بی پرانتز تعریف کنم ، تفاوت اینا تو چیه ؟


class car():
pass

--------------

class car:
pass



ببخشید سطحم خیلی پایینه :خجالت::خجالت::لبخند:

n.nowroozi
چهارشنبه 29 بهمن 1393, 13:55 عصر
ببین فرض کن یه سرور messaging داری که یه شئ از کلاس به اضای هر کانکشن جدید میسازه و شما میخواید به محض اینکه کسی کانکت شد به سرورتون، یه پیغام خوش آمد گویی براش ارسال کنید در چنین مواردی میاید از کلاس init استفاده میکنید و دستوراتی که میخواید به محض ایجاد شئ جدید ایجاد بشه رو توش میزارید که در اینجا میشه ارسال پیغام خوش آمد گویی به کاربر..

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


class Nima(object):
pass

arefenayat
چهارشنبه 29 بهمن 1393, 14:07 عصر
ببین فرض کن یه سرور messaging داری که یه شئ از کلاس به اضای هر کانکشن جدید میسازه و شما میخواید به محض اینکه کسی کانکت شد به سرورتون، یه پیغام خوش آمد گویی براش ارسال کنید در چنین مواردی میاید از کلاس init استفاده میکنید و دستوراتی که میخواید به محض ایجاد شئ جدید ایجاد بشه رو توش میزارید که در اینجا میشه ارسال پیغام خوش آمد گویی به کاربر..


خوب مگر نمیشه توی همون کلاس دستورات رو اجرا کنیم ؟ اونا هم به محض ایجاد کلاس اجرا میشن دیگه ؟
مثلاً اینا چه فرقی دارن ؟


class Athlete:
def __init__(self):
print("salam")


-------------


class Athlete:
print("salam")

n.nowroozi
پنج شنبه 30 بهمن 1393, 07:45 صبح
نه print حالت دوم فقط و فقط یک بار به هنگام تعریف کلاس اجرا میشود در حالی که حالت اول هربار که شما یک شي از کلاس بسازید اجرا میشود.