التغليف: حماية البيانات
نحمي بيانات الكائن من التغيير الخطأ. ⏱ نحو 20 دقيقة.
- تشرح معنى التغليف وفائدته.
- تخفي خاصية بشرطتين سفليتين.
- تكتب دوال آمنة تغيّر الخاصية بعد فحصها.
- تكتب دالة تقرأ الخاصية المخفية.
١المشكلة: أي أحد يغيّر البيانات
في الحساب البنكي لا يحق لأحد أن يكتب الرصيد بيده. لكن انظر ماذا يحدث في هذا الكلاس:
class Account: def __init__(self): self.balance = 100 a = Account()a.balance = -5000print(a.balance)
رصيد سالب بلا أي فحص! نريد أن نمنع التعديل المباشر، ونسمح بالتغيير فقط عبر دوال تفحص القيمة.
٢التغليف: خاصية مخفية
التغليف يعني أن نخفي البيانات داخل الكائن، ونفتح لها «نوافذ» آمنة فقط. مثل الصرّاف الآلي: لا تلمس النقود بيدك، بل تطلب منه، وهو يتحقق.
في بايثون نخفي الخاصية بكتابة شرطتين سفليتين قبل اسمها:
class Account: def __init__(self): self.__balance = 100 a = Account()print(a.__balance)
الخاصية __balance لا يمكن الوصول إليها من خارج الكلاس، فظهر الخطأ AttributeError. هذا ما نريده.
٣نوافذ آمنة: دوال تفحص قبل التغيير
class Account: def __init__(self, owner): self.owner = owner self.__balance = 0 def deposit(self, amount): if amount > 0: self.__balance += amount else: print("المبلغ غير صحيح") def withdraw(self, amount): if amount <= self.__balance: self.__balance -= amount else: print("الرصيد لا يكفي") def get_balance(self): return self.__balance a = Account("سعاد")a.deposit(500)a.withdraw(800)a.withdraw(200)a.deposit(-50)print("الرصيد:", a.get_balance())
الآن لا يتغيّر الرصيد إلا عبر deposit و withdraw، وكل منهما يفحص قبل التنفيذ. ونقرأ الرصيد عبر get_balance.
٤متى نغلّف؟
| الخاصية | نخفيها؟ | السبب |
|---|---|---|
| الرصيد | نعم | لا يتغيّر إلا بشروط |
| الدرجة | نعم | يجب أن تكون بين 0 و 100 |
| كلمة المرور | نعم | لا تُعرض ولا تُقرأ مباشرة |
| اسم صاحب الحساب | غالبًا لا | لا خطر في قراءته |
📎 للاستزادة (اختياري): التغليف في اللغات الأخرى
في Java و C# تُكتب الكلمة private قبل الخاصية. الفكرة واحدة في كل اللغات: البيانات مخفية، والدوال هي البوابة.
توقّع وتحقّق
ما معنى التغليف؟
كيف نخفي الخاصية balance في بايثون؟
ما الخطأ الذي يظهر عند قراءة خاصية مخفية من خارج الكلاس؟
لماذا نكتب دالة get_balance؟
الخلاصة
- التغليف: نخفي البيانات، ونسمح بتغييرها عبر دوال تفحصها.
- الخاصية المخفية تبدأ بشرطتين:
self.__balance - قراءتها من الخارج تعطي
AttributeError. - نكتب دالة للتغيير بشرط، ودالة للقراءة مثل
get_balance.
تحدٍّ برمجي: درجة محمية
متوسطاكتب كلاسًا Student فيه خاصية مخفية __mark تبدأ من 0، ودالة set_mark تقبل الدرجة فقط إذا كانت بين 0 و 100، وإلا تطبع: درجة غير صحيحة. ودالة get_mark تُرجع الدرجة. جرّب الدرجة 150 ثم 85 واطبع الناتج.
self.__mark = 0داخل __init__.- افحص الدرجة:
if 0 <= m <= 100 - اطبع
get_mark()في النهاية.
ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:
class Student: def __init__(self): self.__mark = 0
💡 تلميح 1
def set_mark(self, m):💡 تلميح 2
حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
class Student: def __init__(self): self.__mark = 0 def set_mark(self, m): if 0 <= m <= 100: self.__mark = m else: print("درجة غير صحيحة") def get_mark(self): return self.__mark s = Student()s.set_mark(150)s.set_mark(85)print(s.get_mark())