Jannah Theme License is not validated, Go to the theme options page to validate the license, You need a single license for each domain name.

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

6 أخطاء يجب تجنبها أثناء كتابة البرمجة في Python

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

a-screen-with-the-python-download-webpage-scaled هكذا يتجنب المحترفون أخطاء Python التي تُفسد المشاريع البرمجية

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

6. تعديل قائمة أثناء التكرار

قد يبدو تعديل قائمة بايثون أثناء تكرارها اختصارًا ذكيًا، ولكنه خدعة شائعة في بايثون! قد يؤدي هذا الخطأ الخبيث إلى سلوك غير متوقع، مثل تخطي عناصر أو الحصول على قائمة مشوهة تمامًا.

لنفترض أن لدينا قائمة أرقام، ونريد حذف جميع الأرقام التي تقل عن 5. يبدو الأمر واضحًا، أليس كذلك؟

numbers = [1, 2, 6, 3, 7, 4, 8, 5]
print("Original list:", numbers)

for number in numbers:
   if number < 5:
       numbers.remove(number)

print("Modified list (oops!):", numbers)

إذا قمت بتشغيل هذا الكود، فستجد أن الرقم 2 يبقى في القائمة.

trying-to-modify-a-list-while-iterating-it-in-python هكذا يتجنب المحترفون أخطاء Python التي تُفسد المشاريع البرمجية

لكن لماذا؟ في هذا الكود، نحاول تكرار الأرقام وإزالة العناصر الأقل من 5. مع ذلك، عند إزالة عنصر، تتقلص القائمة، وتتغير مؤشرات العناصر التالية.

قد يؤدي هذا إلى تخطي الحلقة للعناصر. على سبيل المثال، عند إزالة 1، ينتقل 2 إلى موقع 1 القديم، لكن العداد الداخلي للحلقة قد انتقل بالفعل، مما قد يؤدي إلى تخطي 2.

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

numbers = [1, 2, 6, 3, 7, 4, 8, 5]
print("Original list:", numbers)

for number in numbers[:]:  # Iterate over a slice (copy) of the list
   if number < 5:
       numbers.remove(number)

print("Modified list (fixed with copy):", numbers)

باستخدام numbers[:]، ننشئ شريحة من قائمة الأرقام، وهي نسخة سطحية. ثم تتكرر حلقة for على هذه النسخة، مستقلةً تمامًا عن أي تعديلات نُجريها على قائمة الأرقام الأصلية.

اقرأ أيضا:  كيفية تسريع Firestick

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

numbers = [1, 2, 6, 3, 7, 4, 8, 5]
print("Original list:", numbers)

filtered_numbers = [number for number in numbers if number >= 5]
print("Filtered list (new list method):", filtered_numbers)

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

5. تعارضات التسمية

قد يبدو اختيار أسماء المتغيرات والملفات تفصيلًا بسيطًا، إلى أن تُفاجئك بايثون وتُصيبك (مجازيًا). تسمية الأشياء بشكل خاطئ قد تؤدي إلى أخطاء غريبة، ووظائف مُضللة، وساعات من الارتباك. هناك طريقتان شائعتان لحدوث ذلك: استخدام كلمات مفتاحية أو أسماء مدمجة في بايثون على أنها خاصة بك، أو تسمية نصوصك البرمجية عن طريق الخطأ بأسماء وحدات بايثون موجودة.

لن يمنعك Python من تسمية قائمة متغيرات، أو سلسلة نصية، أو حتى مجموع. ولكن مجرد قدرتك على فعل ذلك لا يعني أنه يجب عليك فعله.

list = [1, 2, 3]
print(list)

سيعمل هذا الكود بسلاسة. مع ذلك، إذا أضفت سطرًا آخر يحتوي على دالة list() في بايثون، فسيظهر خطأ.

list = [1, 2, 3]
print(list)

list = list('123')

an-example-of-naming-a-python-list-as-list هكذا يتجنب المحترفون أخطاء Python التي تُفسد المشاريع البرمجية

هذا لأنك استبدلت دالة list() المُدمجة بكائن قائمتك الخاص. عند محاولة استدعاء list(‘123’)، يعتقد بايثون أنك تحاول استدعاء قائمتك الخاصة، وليس الدالة المُدمجة. لذا، استخدم دائمًا أسماءً وصفية لا تتعارض مع ميزات بايثون الأساسية.

numbers = [1, 2, 3]
converted = list('123')

لن يساعدك هذا على تجنب استخدام الكلمات المفتاحية المحجوزة فحسب، بل يُعدّ أيضًا تمرينًا جيدًا لسهولة قراءة الكود وتصحيح أخطائه. وينطبق الأمر نفسه على تسمية ملفات النصوص البرمجية. لنفترض أنك أنشأت ملفًا باسم random.py لتجربة أرقام عشوائية:

# random.py
import random

print(random.randint(1, 10))

ولكن عند تشغيل هذا، من المرجح أن ترى خطأً يُشير إلى أن “الوحدة النمطية ‘random’ لا تحتوي على السمة ‘randint'”. يستورد بايثون ملفك الخاص (random.py) بدلاً من الوحدة النمطية العشوائية الفعلية من المكتبة القياسية. خطأ شائع في التظليل.

تجنب تسمية نصوصك البرمجية باسم وحدات نمطية موجودة مثل random.py أو math.py أو os.py أو json.py. وإذا فعلت ذلك عن طريق الخطأ، فلا تنسَ حذف مجلدات .pyc أو __pycache__ المقابلة بعد إعادة التسمية.

اقرأ أيضا:  كيفية تعيين الخلفية وشاشة التوقف على Chromebook

4. وسيطات الدالة القابلة للتغيير

يسمح لك بايثون بتعيين قيم افتراضية لوسيطات الدالة، وهو أمر مريح للغاية. ولكن عندما تكون هذه القيم الافتراضية قابلة للتغيير (مثل القوائم أو القواميس)، فأنت تقع في فخ خطأ خفي.

يتم إنشاء الكائن القابل للتغيير الافتراضي مرة واحدة فقط، عند تعريف الدالة، وليس في كل مرة يتم استدعاؤها. هذا يعني أنه في حال تعديله، سيبقى هذا التغيير ساريًا حتى الاستدعاء التالي.

def add_item_to_list(item, item_list=[]):
   item_list.append(item)
   return item_list

print(add_item("apple"))
print(add_item("banana"))

عند تشغيل هذا الكود، قد تتوقع أن تبدأ كل عملية استدعاء لدالة add_item_to_list() بقائمة جديدة فارغة إذا لم تُوفرها. مع ذلك، سيُظهر الناتج شيئًا غير متوقع:

using-default-value-for-mutable-type-in-a-python-function-creates-unexpected-behavior هكذا يتجنب المحترفون أخطاء Python التي تُفسد المشاريع البرمجية

استدعينا الدالة مرتين. فلماذا لا تزال “apple” موجودة في الاستدعاء الثاني؟ تُنشأ قائمة item_list مرة واحدة فقط، لذا فإن كل استدعاء للدالة يُعدل القائمة نفسها باستمرار. هذا يؤدي إلى سلوك مفاجئ ومليء بالأخطاء. لإصلاح هذا، يمكنك استخدام “None” كإعداد افتراضي وإنشاء القائمة داخل الدالة:

def add_item_to_list(item, item_list=None):
   if item_list is None:
       item_list = []
   item_list.append(item)
   return item_list

print(add_item("apple"))
print(add_item("banana"))

عند ضبط القيمة الافتراضية على “لا شيء”، تُنشأ قائمة جديدة في كل مرة تُستدعى فيها الدالة.

3. التعامل مع الملفات بطريقة خاطئة

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

file = open('data.txt', 'r')
content = file.read()

print(content)
# Forgot to close the file!

قد يُسبب ترك الملفات مفتوحة مشاكل خطيرة، بل قد يمنع حذفها أو تعديلها بواسطة عمليات أخرى. لذلك، احرص دائمًا على إغلاق الملف بعد الانتهاء من عملياتك. يمكنك القيام بذلك باستخدام دالة close().

file = open('data.txt', 'r')
content = file.read()

print(content)
file.close()

ممارسة أخرى جيدة هي استخدام العبارة with في Python، والتي تتولى تلقائيًا إغلاق الملف نيابةً عنك.

with open('data.txt', 'r') as file:
     content = file.read()
print(content)

تتولى كتلة with جميع عمليات التنظيف خلف الكواليس. بمجرد الخروج من الكتلة، يُغلق بايثون الملف نيابةً عنك. هذا يُجنّبك الحاجة إلى إغلاق الملف يدويًا بنفسك.

2. استيراد كل شيء من وحدة

كمبتدئ، قد يكون من المغري إضافة import * من وحدة في أعلى النص البرمجي والانتهاء من العمل. ولكن مع نمو شيفرتك، يُصبح هذا الاختصار سببًا للفشل.

from math import *
from custom_math import *

print(sqrt(16))

ماذا لو عرّف كلٌّ من math وcustom_math دالة تُسمى sqrt()؟ أيّهما يُستدعى؟ لا يُخبرك بايثون، بل يُلغي الدالة السابقة سرًّا.

اقرأ أيضا:  أشياء يجب معرفتها قبل شراء تلفزيون جديد

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

import math
import custom_math

print(math.sqrt(16))
print(custom_math.sqrt(16))

أو حتى مثل هذا:

from math import sqrt as m_sqrt
from custom_math import sqrt as c_sqrt

print(m_sqrt(16))
print(c_sqrt(16))

الصراحة أفضل من الضمنية (فكرة جوهرية من فلسفة بايثون). أنت دائمًا تعرف ما تستخدمه ومصدره.

1. معالجة الاستثناءات بشكل صحيح

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

try:
   result = 10 / 0
except:
   print("Something went wrong!")

 

using-a-generic-except-block-for-exception-handling-in-python هكذا يتجنب المحترفون أخطاء Python التي تُفسد المشاريع البرمجية

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

try:
   result = 10 / 0
except ZeroDivisionError:
   print("You can't divide by zero!")

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

try:
   value = int(input("Enter a number: "))
   result = 10 / value
except ValueError:
   print("That's not a valid number!")
except ZeroDivisionError:
   print("You can't divide by zero!")

تجنب استخدام “باستثناء:” بمفرده. إذا كان من الضروري التقاط جميع الاستثناءات (نادرًا)، فاستخدم “باستثناء:” وتعامل معه بحذر. من خلال التعامل مع الاستثناءات بدقة، يصبح كودك أكثر قابلية للتنبؤ، وأسهل في التصحيح، وأكثر قدرة على تقديم ملاحظات أكثر فائدة.

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

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

زر الذهاب إلى الأعلى