12 يونيو، 2025
لغات البرمجة

مفاهيم متقدمة في بايثون: الدوال المزخرفة، المولدات، والتوابع السحرية

مخطط المقال (Outline)

  1. مقدمة عن المفاهيم المتقدمة في بايثون
  2. ما هي الدوال المزخرفة (Decorators)؟
    • التعريف
    • الاستخدام العملي
    • متى تستخدم؟
  3. أنواع Decorators الشائعة في بايثون
    • @staticmethod
    • @classmethod
    • @property
    • Decorators المخصصة
  4. المولدات (Generators) في بايثون
    • الفرق بين Generator و Iterator
    • yield مقابل return
    • الأداء والذاكرة
  5. أمثلة عملية على Generators
    • استخدامات في معالجة البيانات الكبيرة
    • دمج مع الحلقات والأوامر الشرطية
  6. التوابع السحرية (Dunder Methods)
    • ما هي ولماذا تُسمى كذلك؟
    • أمثلة مشهورة: __init__, __str__, __repr__, __len__, __call__
  7. إنشاء كائنات Python “ذكية” باستخدام Dunder Methods
    • كيفية تخصيص السلوك الداخلي للكائنات
    • كتابة كود قابل للقراءة وسهل التتبع
  8. كيف تدمج هذه المفاهيم معًا؟
    • مشروع عملي صغير يجمع Decorators وGenerators وDunder Methods
  9. أفضل الممارسات لكتابة كود بايثون احترافي
  10. خاتمة: لماذا هذه المفاهيم تغير طريقة تفكيرك كمبرمج؟
  11. الأسئلة الشائعة (FAQs)

المقال – الجزء الأول (1-5 من المخطط)


مقدمة عن المفاهيم المتقدمة في بايثون

إذا كنت قد قطعت شوطًا لا بأس به في تعلم لغة بايثون، فربما لاحظت أن الأمور تبدأ في التعقيد قليلًا بعد المتغيرات والحلقات والدوال العادية. بايثون ليست فقط لغة سهلة للتعلم، بل هي لغة مرنة بشكل يسمح لك بالوصول لمستويات متقدمة جدًا من الكتابة الإبداعية للكود. اليوم، سنغوص في أعماق ثلاثة مفاهيم قوية جدًا: الدوال المزخرفة (Decorators)، المولدات (Generators)، والتوابع السحرية (Dunder Methods).

هذه المفاهيم تُعتبر أدوات خارقة في يد أي مبرمج محترف، لأنها تُمكنك من كتابة كود أكثر كفاءة، أقل تكرارًا، وأكثر مرونة. ولكنها قد تبدو معقدة في البداية، لذا دعنا نشرحها بأسلوب بسيط وعملي.


ما هي الدوال المزخرفة (Decorators)؟

هل فكرت يومًا في تعديل أو توسيع وظيفة دالة موجودة، دون تغيير الكود الأصلي لها؟ هذا بالضبط ما تفعله الدوال المزخرفة في بايثون. ببساطة، Decorators هي دوال تأخذ دالة أخرى كوسيط، وتضيف لها بعض الوظائف الإضافية.

التعريف

pythonCopyEditdef decorator_function(original_function):
    def wrapper_function():
        print("تم تشغيل الكود الإضافي")
        return original_function()
    return wrapper_function

@decorator_function
def say_hello():
    print("مرحبًا بك في بايثون!")

say_hello()

الناتج سيكون:

CopyEditتم تشغيل الكود الإضافي  
مرحبًا بك في بايثون!

كما ترى، @decorator_function أضافت سطرًا من الكود قبل تنفيذ say_hello بدون أن نلمس say_hello نفسها!

الاستخدام العملي

الدوال المزخرفة تُستخدم بشكل شائع في:

  • التحقق من الصلاحيات في تطبيقات الويب.
  • تسجيل الأحداث (Logging).
  • قياس الأداء (Timing).
  • تنفيذ الأكواد بشروط خاصة.

متى تستخدم؟

استخدم Decorators عندما:

  • ترغب في إعادة استخدام منطق معين في عدة أماكن.
  • تريد فصل الوظائف الثانوية (مثل الطباعة أو التسجيل) عن الوظائف الأساسية.

أنواع Decorators الشائعة في بايثون

1. @staticmethod

يُستخدم لتحويل دالة داخل كلاس إلى دالة ثابتة لا تحتاج إلى self.

pythonCopyEditclass Math:
    @staticmethod
    def add(x, y):
        return x + y

2. @classmethod

يأخذ cls كوسيط بدلًا من self، ويُستخدم للوصول أو تعديل الكلاس ككل.

pythonCopyEditclass MyClass:
    count = 0

    @classmethod
    def increment(cls):
        cls.count += 1

3. @property

تحول دالة إلى خاصية، تُستخدم كمتغير بدون أقواس.

pythonCopyEditclass Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def area(self):
        return 3.14 * self._radius ** 2

4. Decorators مخصصة

أنت أيضًا يمكنك إنشاء Decorator خاص بك لأي هدف. مثلًا، لتسجيل وقت التنفيذ:

pythonCopyEditimport time

def timing_decorator(func):
    def wrapper():
        start = time.time()
        result = func()
        end = time.time()
        print(f"استغرق التنفيذ {end - start} ثانية")
        return result
    return wrapper

المولدات (Generators) في بايثون

هل لاحظت أن بعض البرامج تُعاني من مشاكل في الأداء أو استخدام الذاكرة؟ هنا يأتي دور Generators. إنها طريقة ذكية لإنشاء دوال تُرجع القيم واحدة تلو الأخرى باستخدام yield بدلًا من return.

الفرق بين Generator و Iterator

  • Iterator: كائن يتذكر مكانه داخل التسلسل، ويُستخدم عبر next().
  • Generator: طريقة سهلة لكتابة Iterators دون الحاجة لكتابة كود إضافي.
pythonCopyEditdef count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

yield مقابل return

  • return: تُنهي الدالة وتُرجع القيمة.
  • yield: تُرجع قيمة مؤقتة وتُوقف التنفيذ، ويمكن استئنافه لاحقًا.

الأداء والذاكرة

Generators لا تُخزن كل القيم دفعة واحدة، بل تُنتجها عند الطلب. لذا فهي رائعة عندما تتعامل مع ملفات ضخمة أو عمليات ثقيلة.


أمثلة عملية على Generators

معالجة البيانات الكبيرة

pythonCopyEditdef read_large_file(filename):
    with open(filename) as file:
        for line in file:
            yield line.strip()

بدلًا من تحميل الملف بالكامل في الذاكرة، يتم التعامل مع سطر واحد في كل مرة.

الدمج مع الحلقات الشرطية

pythonCopyEditsquares = (x*x for x in range(10) if x % 2 == 0)
for val in squares:
    print(val)

هذه تقنية تُعرف بـ “Generator Expressions” وهي مكافئة للـ List Comprehensions ولكن بطريقة أكثر كفاءة في الذاكرة.

التوابع السحرية (Dunder Methods)

هل سبق لك أن رأيت دوال مثل __init__, __str__, أو __len__ وتساءلت لماذا تبدأ وتنتهي بشرطتين؟ هذه الدوال تُعرف باسم التوابع السحرية أو Dunder Methods (اختصارًا لـ Double Underscore).

ما هي ولماذا تُسمى كذلك؟

Dunder Methods هي دوال مدمجة في لغة بايثون تُستخدم لتخصيص سلوك الكائنات. اسمها يأتي من شكلها المميز: شرطتان مزدوجتان قبل وبعد اسم الدالة.

تُستخدم هذه الدوال للتفاعل مع العمليات الأساسية للكائنات مثل:

  • التهيئة: __init__
  • الطباعة: __str__
  • المقارنة: __eq__, __lt__, إلخ.
  • الطول: __len__
  • الاستدعاء: __call__

أمثلة مشهورة

pythonCopyEditclass Book:
    def __init__(self, title):
        self.title = title

    def __str__(self):
        return f"كتاب: {self.title}"

    def __len__(self):
        return len(self.title)

book = Book("بايثون المتقدمة")
print(book)         # كتاب: بايثون المتقدمة
print(len(book))    # 16

كما ترى، باستخدام __str__ جعلنا الكائن يظهر بشكل مقروء عند طباعته، و__len__ لتحديد طوله بناءً على طول عنوانه.


إنشاء كائنات Python “ذكية” باستخدام Dunder Methods

واحدة من أقوى استخدامات Dunder Methods هي أنها تتيح لك تخصيص سلوك الكائنات. يمكنك جعل الكائنات تتصرف كأنها أرقام، أو قوائم، أو حتى دوال.

مثال عملي

pythonCopyEditclass Counter:
    def __init__(self):
        self.count = 0

    def __call__(self):
        self.count += 1
        return self.count

الآن:

pythonCopyEditc = Counter()
print(c())  # 1
print(c())  # 2

لاحظ أنك استدعيت الكائن وكأنه دالة! هذه هي قوة __call__.

كائنات قابلة للتخصيص بالكامل

باستخدام مجموعة من Dunder Methods، يمكن للكائنات أن تصبح:

  • قابلة للفهرسة (__getitem__)
  • قابلة للتكرار (__iter__)
  • قابلة للمقارنة (__eq__, __lt__)
  • قابلة للجمع (__add__, __sub__)

مثال:

pythonCopyEditclass Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

كيف تدمج هذه المفاهيم معًا؟

الآن نصل إلى الجزء الممتع! كيف يمكننا استخدام Decorators + Generators + Dunder Methods في مشروع واحد؟ لنأخذ مثالًا عمليًا:

مشروع: نظام تسجيل دخول بسيط

pythonCopyEditimport time

def logger(func):
    def wrapper(*args, **kwargs):
        print(f"تنفيذ الدالة: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

class LoginSystem:
    def __init__(self, users):
        self.users = users

    def __iter__(self):
        for user in self.users:
            yield user

    def __str__(self):
        return f"عدد المستخدمين: {len(self.users)}"

    @logger
    def authenticate(self, username):
        if username in self.users:
            print(f"{username} مسموح له بالدخول.")
        else:
            print(f"{username} غير مسجل.")

الاستخدام

pythonCopyEditsystem = LoginSystem(["ahmed", "sara", "noor"])
for u in system:
    print(u)

system.authenticate("sara")
print(system)

هذا المثال يجمع بين:

  • Decorator لتسجيل الدخول.
  • Generator لتكرار المستخدمين.
  • Dunder Methods لعرض معلومات النظام.

أفضل الممارسات لكتابة كود بايثون احترافي

لكي تكتب كود Python متقدم واحترافي، إليك أهم النصائح:

  1. استخدم Decorators للفصل بين المهام.
  2. استخدم Generators لتقليل استهلاك الذاكرة.
  3. استخدم Dunder Methods لتخصيص سلوك الكائنات.
  4. اكتب كود نظيف، واضح، وسهل القراءة.
  5. قم بتوثيق كل دالة وما تفعله، حتى لو كانت واضحة لك الآن.

خاتمة: لماذا هذه المفاهيم تغير طريقة تفكيرك كمبرمج؟

عندما تتقن المفاهيم المتقدمة في بايثون، أنت لا تتعلم فقط بناء كود، بل تتعلم تصميم حلول ذكية وفعالة. الدوال المزخرفة تساعدك على كتابة كود قابل لإعادة الاستخدام، المولدات تحافظ على الأداء، والتوابع السحرية تمنحك القدرة على تصميم كائنات تتصرف كما تريد بالضبط.

باختصار؟ هذه الأدوات تجعل منك مبرمجًا بايثونيًا “محترفًا” بحق.


الأسئلة الشائعة (FAQs)

1. ما الفرق بين Generator و Iterator؟
Generator هو نوع خاص من Iterator يُكتب بشكل أسهل باستخدام yield، بينما Iterator يتطلب استخدام __iter__ و__next__.

2. هل يمكن استخدام أكثر من Decorator على نفس الدالة؟
نعم، ويمكنك تكديسهم مثل:

pythonCopyEdit@decorator1  
@decorator2  
def my_function(): pass

3. متى أستخدم Dunder Methods؟
عندما تريد تعديل أو تخصيص سلوك الكائنات مثل التهيئة أو الطباعة أو الجمع.

4. هل Generators مناسبة للتطبيقات الحية (real-time)?
بالتأكيد! خاصة عندما تكون البيانات كثيرة أو تتغير باستمرار.

5. هل Decorators تضر بأداء البرنامج؟
في العادة لا، ولكن إذا أُسيء استخدامها أو تم تداخلها بشكل غير فعال قد تؤثر سلبًا.

Leave feedback about this