١. المقدمة
Python هي لغة برمجة عامة متعددة الاستخدامات يمكن استخدامها في مجموعة واسعة من المهام، وتُستَخدم تراكيب الحلقات بشكل متكرر في كل برنامج تقريبًا. يسمح لك استخدام الحلقات بتكرار عمليات محددة، وهو أمر أساسي لتحسين كفاءة البرنامج. توفر Python عبارات حلقة مثل “while” و “for”، ومن بينها يمكن أن تكون الحلقات اللانهائية مفيدة في بعض الحالات.
 ما هي الحلقة اللانهائية؟
 الحلقة اللانهائية هي حلقة لا تملك شرط إيقاف أو تم تصميمها عمدًا لتستمر في تنفيذها المتكرر إلى ما لا نهاية. تُستَخدم مثل هذه الحلقات، على سبيل المثال، عندما يجب على خادم أن يعمل باستمرار وينتظر طلبات محددة. بينما يمكن توظيف الحلقات اللانهائية عن قصد، من الممكن أيضًا الوقوع فيها عن طريق الخطأ، لذا فإن فهم الاستخدام الصحيح وكيفية الخروج منها أمر مهم.
 الاستخدامات العملية ومخاطر الحلقات اللانهائية
 تكون الحلقات اللانهائية مفيدة جدًا في الحالات التي يجب فيها على البرنامج الاستمرار في العمل حتى يتحقق شرط معين، مثل جمع البيانات في الوقت الحقيقي أو عمليات الانتظار التي تحتاج إلى البقاء نشطة. ومع ذلك، فإن استخدام حلقة لانهائية بشكل غير صحيح قد يمنع البرنامج من الإنهاء الطبيعي وقد يستهلك موارد النظام. لذلك، عند توظيف الحلقات اللانهائية، يجب تحديد شروط خروج أو فواصل مناسبة واتخاذ خطوات لتقليل الحمل على النظام.
 في هذه المقالة سنستعرض طرقًا مختلفة لإنشاء حلقات لانهائية في Python ونناقش النقاط الرئيسية التي يجب الانتباه إليها. سنغطي أيضًا كيفية إنهاء حلقة لانهائية بأمان ونقدم أمثلة شفرة واقعية، مقدِّمين معلومات مفيدة للجميع من المبتدئين إلى المتقدمين.
 
٢. الطرق الأساسية لإنشاء حلقات لا نهائية في بايثون
هناك عدة طرق أساسية لإنشاء حلقات لا نهائية في Python. عادةً ما يكون استخدام “while loop” أو “for loop” شائعًا، ويمكنك أيضًا الاستفادة من وحدة itertools ودالة iter. هنا سنستعرض كل طريقة لإنشاء حلقات لا نهائية.
حلقة لا نهائية باستخدام حلقة while
أبسط طريقة لإنشاء حلقة لا نهائية هي استخدام تعبير شرط while True:. تقوم عبارة while بتنفيذ المعالجة المتكررة طالما أن الشرط المحدد هو True. لذلك، بمجرد ضبط تعبير الشرط على True، يمكنك إبقاء الحلقة تعمل إلى ما لا نهاية.
 الصيغة الأساسية:
while True:
    print("This message will be printed indefinitely")
في الشيفرة أعلاه، لأن شرط عبارة while دائمًا True، تستمر دالة print في التنفيذ إلى ما لا نهاية. تكون هذه الحلقة اللانهائية مفيدة عندما يحتاج البرنامج إلى تنفيذ إجراء معين باستمرار (على سبيل المثال، انتظار الطلبات على خادم).
حلقة لا نهائية باستخدام حلقة for ووحدة itertools
من خلال دمج عبارة for في Python مع وحدة المكتبة القياسية itertools، يمكنك أيضًا تحقيق حلقات لا نهائية. توفر itertools دوالًا مثل count() و cycle() و repeat() لإنشاء حلقات لا نهائية.
- count() : ينشئ حلقة تزيد الأعداد إلى ما لا نهاية.
   from itertools import count
   for i in count(1):
       print(i)
       if i >= 10:  # Arbitrary termination condition
           break
- cycle() : يعالج قائمة أو تسلسل محدد بشكل متكرر.
   from itertools import cycle
   for item in cycle(['A', 'B', 'C']):
       print(item)
       # In this example, since there's no stop condition, it keeps printing 'A', 'B', and 'C' forever
- repeat() : يطبع قيمة واحدة بشكل متكرر إلى الأبد.
   from itertools import repeat
   for item in repeat("Python", 5):  # You can specify the number of repetitions with the second argument
       print(item)
تُعد هذه الدوال في itertools مفيدة لتكرار تسلسلات أو قيم محددة عندما تكون الحلقة اللانهائية مطلوبة. كما أن كتابة الكود يصبح أكثر اختصارًا، مما يحسن من قابلية القراءة.
حلقة لا نهائية باستخدام الدالة iter
دالة iter() في بايثون تساعد أيضًا في إنشاء حلقات لا نهائية يمكن أن تنتهي تحت ظروف محددة. في دالة iter()، تحدد كائنًا قابلًا للاستدعاء كالمعامل الأول وقيمة إيقاف (sentinel) كالمعامل الثاني. تنتهي الحلقة عندما يكون ناتج استدعاء المعامل الأول مساويًا لـ sentinel، وإلا تستمر الحلقة اللا نهائية.
مثال:
def input_func():
    return input("Enter text (type 'exit' to quit): ")
for value in iter(input_func, 'exit'):
    print(f"Input: {value}")
في الشيفرة أعلاه، يمكن للمستخدم الاستمرار في إدخال سلاسل نصية إلى ما لا نهاية حتى يكتب exit. باستخدام هذه الطريقة، يمكنك بسهولة إنشاء حلقة لا نهائية بشرط إيقاف محدد.
3. كيفية الخروج من حلقة لا نهائية
تستمر الحلقة اللا نهائية حتى يتحقق شرط معين، ولكن إذا حدثت حلقة لا نهائية غير مقصودة، قد يصبح البرنامج غير قادر على الإنهاء. لذلك، من المهم إعداد طرق مناسبة للخروج من الحلقات اللا نهائية والاستعداد للمشكلات المحتملة. فيما يلي بعض الطرق الشائعة للخروج من حلقة لا نهائية.
الخروج من الحلقة باستخدام عبارة break
استخدام عبارة break في بايثون يتيح لك الخروج من الحلقة عندما يتحقق شرط معين. من خلال تعيين شرط داخل الحلقة اللا نهائية، يمكنك الخروج من الحلقة باستخدام عبارة break عندما يصبح ذلك الشرط صحيحًا.
مثال:
while True:
    user_input = input("Please enter something (type 'exit' to stop the loop): ")
    if user_input == 'exit':
        print("Exiting the loop.")
        break
    print(f"Entered text: {user_input}")
في الشيفرة أعلاه، عندما يُدخل المستخدم "exit"، يتم تنفيذ عبارة break، مما ينهي الحلقة اللا نهائية. من خلال توفير كلمات مفتاحية أو شروط محددة، تسمح للمستخدم بإيقاف الحلقة رغبته.
الإنهاء القسري باستخدام KeyboardInterrupt (Ctrl + C)
عند تشغيل برنامج في بيئة تطوير متكاملة أو في الطرفية، إذا رفضت حلقة لا نهائية التوقف، يمكنك رفع استثناء KeyboardInterrupt لإجبار البرنامج على الإنهاء. يتم ذلك بالضغط على “Ctrl + C” (نفس الاختصار على كل من ماك وويندوز).
try:
    while True:
        print("Press Ctrl + C to exit")
except KeyboardInterrupt:
    print("The program was forcibly terminated.")
تُظهر هذه الشيفرة كيفية التقاط استثناء KeyboardInterrupt لإنهاء الحلقة اللا نهائية. عادةً ما تقوم بإنهاء الحلقة بالقوة باستخدام Ctrl + C، ولكن باستخدام معالجة الاستثناءات يمكنك أيضًا عرض رسالة عند الإنهاء القسري.
إنهاء العملية عبر مدير المهام أو مراقب النشاط
إذا تسببت حلقة لا نهائية في جعل برنامج بايثون غير مستجيب ولا يمكن إيقافه باستخدام Ctrl + C، يمكنك إيقاف العملية بالقوة باستخدام مدير المهام في نظام التشغيل أو مراقب النشاط.
- ويندوز: افتح مدير المهام (Ctrl + Shift + Esc)، ابحث عن عملية “Python”، وانقر على “End Task”.
- ماك: افتح مراقب النشاط، اختر عملية “Python”، وانقر على “Quit”.
إنهاء العملية بهذه الطريقة سيوقف الحلقة اللا نهائية بالقوة، لكن احذر من فقدان أي بيانات غير محفوظة. 
4. اعتبارات وأمثلة عملية على الحلقات اللا نهائية
يمكن للحلقات اللا نهائية الاستمرار في التنفيذ حتى يتحقق شرط معين، مما يجعلها مفيدة في العديد من السيناريوهات. ومع ذلك، يتطلب استخدام الحلقات اللا نهائية إدارة دقيقة. فهم خصائص ومخاطر الحلقات اللا نهائية واستخدامها بشكل مناسب أمر أساسي.
اعتبارات للحلقات اللا نهائية
- حدوث حلقة لا نهائية غير مقصودة 
 تظهر الحلقات اللا نهائية عادةً عندما لا توجد شرط إنهاء مناسب، مما قد يفرض حملًا غير متوقع على النظام. على وجه الخصوص، إذا تم ضبط شرط الإنهاء بشكل غير صحيح أو كان موضع جملة- breakغير مناسب، فهناك خطر الوقوع في حلقة لا نهائية. لذلك يُنصح بإدراج نقاط فحص دورية أثناء معالجة الحلقة اللا نهائية.
- استهلاك موارد المعالج (CPU) 
 إذا تُركت دون مراقبة، تستهلك الحلقات اللا نهائية كمية كبيرة من موارد المعالج. على وجه الخصوص، إذا لم تُدخل وقت انتظار ثابت داخل الحلقة باستخدام دوال مثل- time.sleep()، سيخصص المعالج جميع موارده لمعالجة الحلقة، مما قد يضعف أداء النظام ككل. مثال :
   import time
   while True:
       print("Running while conserving resources...")
       time.sleep(1)  # Set a 1-second wait time
بهذه الطريقة، يضيف استخدام time.sleep() تأخيرًا طفيفًا في معالجة الحلقة اللا نهائية، مما يقلل من استهلاك المعالج ويسمح بإدارة أكثر كفاءة للحلقة اللا نهائية.
- تحديد شروط إنهاء مناسبة
 إذا لم تكن شروط الإنهاء واضحة، قد تستمر الحلقة إلى ما لا نهاية، لذا من المهم التخطيط مسبقًا للظروف التي يجب أن تنتهي فيها الحلقة. الاستفادة من المشغلات الخارجية مثل المدخلات أو الإشارات هي إحدى الطرق. بالإضافة إلى ذلك، من خلال دمج معالجة الاستثناءات وصياغةtry-exceptللحالات التي لا تُستوفى فيها الشروط، يمكنك منع توقف الكود بسبب أخطاء غير متوقعة.
أمثلة عملية على الحلقات اللا نهائية
- جمع البيانات في الوقت الحقيقي
 تُناسب الحلقات اللا نهائية التطبيقات التي تجمع البيانات في الوقت الحقيقي. على سبيل المثال، السكريبتات التي تتحقق باستمرار من وجود مشاركات أو تعليقات جديدة عبر واجهات برمجة تطبيقات وسائل التواصل الاجتماعي، أو الأنظمة التي تستقبل بيانات المستشعرات من أجهزة إنترنت الأشياء بشكل مستمر، تستفيد من الحلقات اللا نهائية. مثال :
   import time
   def collect_data():
       # Write the data collection logic here
       print("Collecting data...")
   while True:
       collect_data()
       time.sleep(5)  # Collect data every 5 seconds
- انتظار طلبات الخادم 
 تُستخدم الحلقات اللا نهائية عندما ينتظر الخادم باستمرار الطلبات ويعالجها. على سبيل المثال، تحتاج الروبوتات الحوارية وخوادم HTTP إلى الانتظار باستمرار لطلبات المستخدم والرد عليها. في مثل هذه الحلقات، يُصمم البرنامج بحيث لا يتوقف تلقائيًا إلا إذا أرسل المستخدم طلبًا.
- حلقة اللعبة الرئيسية 
 في تطوير الألعاب، تتحقق الحلقة الرئيسية باستمرار من عمليات الرسم وإدخال المستخدم، مما يضمن سلاسة اللعب. طالما استمر اللاعب في التفاعل، تقوم الحلقة اللا نهائية بتحديث الشاشة، ومعالجة الإدخال، والحفاظ على تقدم اللعبة. مثال :
   running = True
   while running:
       # Check player input
       # Update screen rendering
       # Update game state
       if some_exit_condition:
           running = False
أن تكون الحلقات اللا نهائية مفيدة للغاية عندما تُستَخدم بشكل مناسب، لكن يتطلب ذلك مراعاة دقيقة لاستخدام الموارد ومخاطر الإنهاء غير المقصود. للحفاظ على انخفاض حمل النظام أثناء تنفيذ حلقات فعّالة، من الضروري وضع استراتيجيات مثل تحديد أوقات الانتظار، وتعريف شروط الإنهاء، والاستفادة من المشغلات الخارجية.
5. أمثلة شفرة عملية
هنا نقدم عدة أمثلة شفرة ملموسة لتنفيذ الحلقات اللا نهائية في بايثون. سنتعلم خطوة بخطوة، من أساسيات الحلقات اللا نهائية إلى طرق كسرها تحت ظروف معينة، وإلى تطبيقات متقدمة للحلقات اللا نهائية.
حلقة لا نهائية أساسية
أبسط حلقة لا نهائية في بايثون هي الطريقة التي تستخدم while True. بما أن True دائمًا صحيحة، تتكرر الحلقة إلى ما لا نهاية ما لم يتم توفير شرط إنهاء.
 مثال: الصياغة الأساسية لحلقة لا نهائية
while True:
    print("This will be printed forever")
في هذا الكود، تعمل دالة print() بلا توقف، ولا ينتهي البرنامج أبداً. يمكن أن تثقل مثل هذه الحلقة اللانهائية النظام بشكل غير مقصود إذا لم يتم تعيين شرط إنهاء محدد، كما هو موضح لاحقاً، لذا يتطلب الأمر الحذر.
حلقة لانهائية مع انقطاع شرطي
باستخدام بيان break داخل حلقة لانهائية، يمكنك الخروج من الحلقة عند تحقق شروط معينة. على سبيل المثال، يمكنك تهيئة الحلقة للإنهاء عندما يتطابق إدخال المستخدم مع قيمة محددة. مثال: إنهاء حلقة لانهائية عبر الإدخال
while True:
    user_input = input("Type 'exit' to stop the loop: ")
    if user_input == "exit":
        print("Exiting the loop.")
        break
    print(f"Entered text: {user_input}")
في هذا المثال، عندما يدخل المستخدم “exit”، تنتهي الحلقة ببيان break. هذا النهج مناسب للبرامج التفاعلية لأنه يسمح بالتحكم الديناميكي في الحلقة بناءً على إدخال المستخدم.
توفير الموارد باستخدام time.sleep()
عندما تعمل حلقة لانهائية بسرعة عالية، فإنها تستهلك موارد الـ CPU، لذا يمكنك تقليل استخدام الـ CPU من خلال إيقاف التنفيذ مؤقتاً باستخدام دالة time.sleep(). مثال: حلقة لانهائية مع تأخيرات
import time
while True:
    print("Running while saving resources...")
    time.sleep(1)  # wait every 1 second
باستخدام time.sleep() بهذه الطريقة، تعمل الحلقة مرة واحدة في الثانية، مما يساعد في كبح استهلاك الموارد غير الضروري. إنه مفيد عندما تحتاج إلى جمع بيانات أو معالجة معلومات على فترات.
حلقات لانهائية باستخدام وحدة itertools
توفر وحدة itertools في Python دوال count() و cycle() المناسبة جيداً للحلقات اللانهائية. باستخدام هذه الدوال، يمكنك إنشاء حلقات تكرر تسلسلاً بلا نهاية بسهولة. مثال: حلقة لانهائية مع عداد باستخدام count()
from itertools import count
for i in count(1):
    print(i)
    if i >= 10:  # arbitrary termination condition
        break
في هذا المثال، ينشئ count(1) عداداً لانهائياً يبدأ من 1، وتكرر حلقة for ذلك. عندما يصل i إلى 10 أو أكثر، تخرج الحلقة ببيان break، مما يجعلها مفيدة جداً للتحكم في الحلقات اللانهائية.
حلقة لانهائية تنتظر إدخال المستخدم
عند تشغيل حلقة لانهائية تنتظر إدخال المستخدم، يمكنك تنفيذها بكفاءة باستخدام دالة iter(). المثال أدناه ينشئ حلقة تقبل الإدخال باستمرار حتى يكتب المستخدم “exit”. مثال: حلقة لانهائية باستخدام iter() وشرط إنهاء
def get_input():
    return input("Please enter text (type 'exit' to exit): ")
for user_input in iter(get_input, 'exit'):
    print(f"Entered text: {user_input}")
في هذا المثال، تدعو دالة iter() دالة get_input مراراً وتكراراً، وتستمر الحلقة حتى يتم إدخال “exit”. هذه الطريقة مفيدة للخروج من حلقة لانهائية يثيرها إدخال مستخدم محدد. 
6. الملخص
الحلقات اللانهائية في Python أداة قوية مفيدة لأغراض متنوعة. في هذه المقالة غطينا أساسيات الحلقات اللانهائية في Python، أمثلة عملية، وكود حقيقي بالتفصيل. بينما الحلقات اللانهائية مريحة، إساءة الاستخدام يمكن أن تضع حملاً عالياً على النظام أو تؤدي إلى سلوك غير متوقع، لذا يتطلب الأمر الحذر.
مراجعة النقاط الرئيسية
- الهيكل الأساسي للحلقات اللانهائية 
 عند إنشاء حلقة لانهائية في بايثون، هناك صيغ تستخدم- while Trueوعبارات- for، وفهم هذه الصيغ يتيح إنشاء حلقات لانهائية بكفاءة. كما أن استخدام وحدة- itertoolsيجعل من السهل تنفيذ عدادات تتزايد بلا نهاية أو سلاسل متكررة.
- كيفية إيقاف الحلقات اللانهائية 
 معرفة طرق الإنهاء مثل عبارات- breakو- KeyboardInterrupt(Ctrl + C) تتيح لك التحكم المتعمد في الحلقات اللانهائية. استخدام تقنيات الإيقاف بشكل مناسب يضمن برامج آمنة وفعّالة.
- حالات الاستخدام العملية 
 الحلقات اللانهائية مفيدة في العديد من السيناريوهات مثل جمع البيانات في الوقت الحقيقي، الانتظار لطلبات الخادم، وحلقات اللعبة الرئيسية. بالإضافة إلى ذلك، استخدام- time.sleep()للحفاظ على انخفاض استهلاك المعالج يساعد في تقليل حمل النظام مع الاستفادة الفعّالة من الحلقات اللانهائية.
لاستخدام الحلقات اللانهائية بشكل صحيح، من المهم مراعاة شروط الإنهاء وإدارة الموارد أثناء التصميم. من خلال تطبيق المعرفة والتقنيات المناسبة، يمكنك الاستفادة من الحلقات اللانهائية لإنشاء برامج أكثر قوة وكفاءة.

 
 


