Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

محددات الوصول

جزء من قسم Object Oriented Programming في رحلة Python على Coddy — الدرس 29 من 64.

تتحكم معدلات الوصول في رؤية خصائص وطرق الفئة. تستخدم بايثون اتفاقيات التسمية بدلاً من الكلمات المفتاحية للتحكم في الوصول.

إليك مثال على الوصول العام (بدون بادئة):

class Person:
    def __init__(self):
        self.name = "Coddy"      # سمة عامة
        
    def greet(self):             # طريقة عامة
        return f"Hello, I'm {self.name}"

الوصول إلى الأعضاء العامين من أي مكان:

person = Person()
print(person.name)           # Coddy
print(person.greet())        # مرحباً، أنا Coddy

إليك مثال على الوصول المحمي (شرطة سفلية واحدة):

class Employee:
    def __init__(self):
        self._salary = 50000     # سمة محمية
    
    def _calculate_bonus(self):  # طريقة محمية
        return self._salary * 0.1

    def show_bonus(self):
        return self._calculate_bonus()  # من المقبول استخدامها داخل الفئة

الوصول إلى الأعضاء المحميين (يعمل ولكن لا يُنصح به):

employee = Employee()
print(employee._salary)      # 50000 - يعمل ولكن لا يُنصح به
print(employee.show_bonus()) # 5000.0 - الطريقة الصحيحة

إليك مثال على الوصول الخاص (الشرطة السفلية المزدوجة):

class User:
    def __init__(self):
        self.__password = "secure123"   # سمة خاصة
        
    def __encrypt(self, data):          # طريقة خاصة
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        # الأعضاء الخاصون يمكن الوصول إليهم داخل الفئة
        return input_password == self.__password

استخدم الأعضاء الخاصين بشكل صحيح:

user = User()
print(user.verify("secure123"))  # True - استخدام طريقة عامة
# print(user.__password)         # AttributeError - لا يمكن الوصول إليه مباشرة

المخرجات:

Coddy
Hello, I'm Coddy
50000
5000.0
True

نقطة رئيسية: معدلات الوصول في Python هي عبارة عن اتفاقيات تسمية: بدون بادئة = public (يمكن الوصول إليه من أي مكان)، شرطة سفلية واحدة = protected (للاستخدام الداخلي)، شرطة سفلية مزدوجة = private (للفئة class فقط). تساعد هذه في وضع حدود واضحة ومنع سوء الاستخدام العرضي للأجزاء الداخلية للفئة.

challenge icon

التحدي

متوسط

في هذا التحدي، ستقوم بتنفيذ فئة FileManager التي توضح معدلات الوصول في Python (العامة والمحمية والخاصة) مع تجربة فوائد الاختبار الشامل.

قم بتحرير filemanager.py لتنفيذ فئة FileManager باتباع تعليقات TODO. يحتوي الملف على تعليمات مفصلة لتنفيذ ما يلي:

  • الأساليب العامة (Public methods) لعمليات الملفات
  • الأساليب المحمية (Protected methods) (مع بادئة شرطة سفلية واحدة)
  • الأساليب الخاصة (Private methods) (مع بادئة شرطة سفلية مزدوجة)
  • تفاعلات الأساليب التي توضح التغليف (encapsulation)

ورقة مرجعية

تستخدم بايثون (Python) اصطلاحات التسمية للتحكم في الوصول:

الوصول العام (Public access) (بدون بادئة) - يمكن الوصول إليه من أي مكان:

class Person:
    def __init__(self):
        self.name = "Coddy"      # سمة عامة
        
    def greet(self):             # طريقة عامة
        return f"Hello, I'm {self.name}"

person = Person()
print(person.name)           # Coddy
print(person.greet())        # Hello, I'm Coddy

الوصول المحمي (Protected access) (شرطة سفلية واحدة) - للاستخدام الداخلي، ولا ينصح به من الخارج:

class Employee:
    def __init__(self):
        self._salary = 50000     # سمة محمية
    
    def _calculate_bonus(self):  # طريقة محمية
        return self._salary * 0.1

employee = Employee()
print(employee._salary)      # يعمل ولكن لا ينصح به

الوصول الخاص (Private access) (شرطة سفلية مزدوجة) - للفئة (class) فقط:

class User:
    def __init__(self):
        self.__password = "secure123"   # سمة خاصة
        
    def __encrypt(self, data):          # طريقة خاصة
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        return input_password == self.__password

user = User()
print(user.verify("secure123"))  # True - باستخدام طريقة عامة
# print(user.__password)         # AttributeError - لا يمكن الوصول إليه مباشرة

جرّب بنفسك

from file_manager import FileManager

# معالج حالات الاختبار الشاملة
test_case = input()

if test_case == "basic_test":
    # إنشاء مثيل من FileManager
    manager = FileManager()
    # استدعاء التابع read_file
    print(manager.read_file("example.txt"))
    # استدعاء التابع get_file_content
    print(manager.get_file_content("example.txt"))

elif test_case == "protected_access":
    # إنشاء مثيل من FileManager
    manager = FileManager()
    # محاولة استدعاء التابع المحمي
    # التوابع المحمية يمكن الوصول إليها ولكنها مخصصة للاستخدام الداخلي
    print(manager._check_permissions("example.txt"))
    print("Note: Protected methods are accessible but intended for internal use only")

elif test_case == "private_access":
    # إنشاء مثيل من FileManager
    manager = FileManager()
    try:
        # محاولة استدعاء التابع الخاص مباشرة
        print(manager.__decrypt_content("some content"))
    except AttributeError as e:
        print(f"Error: {e}")
        print("Private methods are name-mangled and cannot be accessed directly")
    
    # الوصول باستخدام صيغة الاسم المشوه (name-mangled)
    print(manager._FileManager__decrypt_content("some content"))
    print("Note: Accessed private method using name-mangled form")

elif test_case == "method_chaining":
    # إنشاء مثيل من FileManager
    manager = FileManager()
    # توضيح كيف يقوم get_file_content باستدعاء كل من التوابع المحمية والخاصة داخلياً
    print("Calling get_file_content which internally uses protected and private methods:")
    print(manager.get_file_content("example.txt"))

elif test_case == "multiple_files":
    # إنشاء مثيل من FileManager
    manager = FileManager()
    # معالجة ملفات متعددة
    files = ["document.txt", "image.jpg", "data.csv"]
    
    for file in files:
        print(f"\
Processing {file}:")
        print(manager.read_file(file))
        print(manager.get_file_content(file))

elif test_case == "name_mangling":
    # إنشاء مثيل من FileManager
    manager = FileManager()
    # توضيح تشويه الأسماء (name mangling)
    print("Python's name mangling for private methods:")
    print("Attempting direct access would fail with AttributeError")
    print("Using mangled name:")
    print(manager._FileManager__decrypt_content("private data"))
    print("\
Name mangling is Python's mechanism to prevent accidental access")
    print("It renames __method to _ClassName__method internally")
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming