الكلاسات والأوبجكتس
إزاي تجمع البيانات والأفعال المرتبطة بيها في حتة واحدة.
المشكلة اللي بتحلها
تخيل بتعمل سيستم لبنك فيه ألف حساب. كل حساب ليه اسم صاحبه ورصيد، وبيحصل عليه إيداع وسحب. لو استخدمت dicts و functions متفرقة، الكود هيبقى لخبطة. الـ OOP (البرمجة الكائنية) بتخليك تجمع البيانات (الرصيد) والأفعال (السحب) في حتة واحدة اسمها class.
الـ Class غير الـ Object
الـ class هو التصميم أو الكتالوج، زي تصميم عربية في المصنع. الـ object هو النسخة الحقيقية المعمولة من التصميم ده، زي العربية اللي انت راكبها. من تصميم واحد بتطلع آلاف العربيات، كل واحدة ليها لونها ورقم شاسيهها.
class BankAccount: # __init__ runs automatically when you create a new object def __init__(self, owner, balance=0): self.owner = owner # attribute (data) self.balance = balance # method (behavior) def deposit(self, amount): self.balance += amount print(f"{self.owner}: deposited {amount}, balance = {self.balance}") def withdraw(self, amount): if amount > self.balance: print(f"{self.owner}: insufficient balance!") return self.balance -= amount print(f"{self.owner}: withdrew {amount}, balance = {self.balance}") # Create two separate objects from the same class ahmed = BankAccount("Ahmed", 5000) mona = BankAccount("Mona") ahmed.withdraw(1500) mona.deposit(800) mona.withdraw(1000)
class التصميم اللي بتعمل منه أوبجكتس.object نسخة حقيقية من الكلاس، وبيسموها instance برضو.attribute بيانات جوه الأوبجكت زي balance.method function جوه الكلاس، بتعبر عن فعل زي withdraw.__init__ الـ constructor، بيتنفذ لوحده أول ما تعمل أوبجكت جديد.يعني إيه self؟
self معناها «الأوبجكت ده نفسه». لما تكتب ahmed.withdraw(1500)، بايثون بتبعت ahmed مكان self من غير ما تحس. عشان كده self.balance جوه الميثود معناها «رصيد الحساب اللي نادى عليا دلوقتي»، فرصيد أحمد مبيتلخبطش مع رصيد منى.
self. لو نسيته هيطلعلك TypeError بيقول إن الدالة أخدت arguments أكتر من المتوقع.خلّي الأوبجكت يتطبع بشكل حلو
لو عملت print(ahmed) هيطلعلك حاجة غريبة زي <__main__.BankAccount object at 0x7f...>. الميثود الخاصة __str__ بتحدد الأوبجكت يتطبع إزاي. الميثودز اللي اسمها بين __ بيسموها magic methods أو dunder methods.
class Product: def __init__(self, name, price): self.name = name self.price = price def __str__(self): return f"{self.name} - {self.price:,} EGP" phone = Product("Galaxy A55", 17999) print(phone)
class MyModel(nn.Module): وجواه __init__ بتعرّف فيها الطبقات، وميثود forward بتحدد الداتا بتمشي إزاي. نفس الشكل اللي اتعلمته هنا بالظبط.