بقلم روبيش شارما المعروف أيضًا باسم @hackyrupesh
تعد بايثون ببساطتها وجمالها إحدى لغات البرمجة الأكثر شعبية في العالم. ومع ذلك، حتى في عام 2024، ستستمر بعض العيوب في إزعاج المطورين. لا ترجع هذه المشكلات دائمًا إلى نقاط الضعف في لغة بايثون، بل إلى تصميمها أو سلوكها أو المفاهيم الخاطئة الشائعة التي تؤدي إلى نتائج غير متوقعة. في مقالة المدونة هذه، سنلقي نظرة على أهم 5 مشكلات في لغة Python لا يزال كل مطور يواجهها في عام 2024، بالإضافة إلى علاجاتها.
واحدة من أكثر أخطاء بايثون شهرة هي الوسيطة الافتراضية القابلة للتغيير. عند استخدام كائن قابل للتغيير (مثل القائمة أو القاموس) كوسيطة افتراضية في دالة، تقوم بايثون بتقييم هذه الوسيطة الافتراضية مرة واحدة فقط عندما يتم تعريف الوظيفة، وليس في كل مرة يتم استدعاء الوظيفة. يؤدي هذا إلى سلوك غير متوقع عندما تقوم الوظيفة بتعديل الكائن.
def append_to_list(value, my_list=[]): my_list.append(value) return my_list print(append_to_list(1)) # Outputs: [1] print(append_to_list(2)) # Outputs: [1, 2] - Unexpected! print(append_to_list(3)) # Outputs: [1, 2, 3] - Even more unexpected!
لتجنب ذلك، استخدم لا شيء كوسيطة افتراضية وقم بإنشاء قائمة جديدة داخل الوظيفة إذا لزم الأمر.
def append_to_list(value, my_list=None): if my_list is None: my_list = [] my_list.append(value) return my_list print(append_to_list(1)) # Outputs: [1] print(append_to_list(2)) # Outputs: [2] print(append_to_list(3)) # Outputs: [3]
يحدث خطأ في المفتاح عند محاولة الوصول إلى مفتاح قاموس غير موجود. قد يكون هذا أمرًا صعبًا بشكل خاص عند العمل مع القواميس المتداخلة أو عند التعامل مع البيانات التي لا يمكن ضمان بنيتها.
data = {'name': 'Alice'} print(data['age']) # Raises KeyError: 'age'
لمنع KeyError، استخدم طريقة get()، التي تُرجع بلا (أو قيمة افتراضية محددة) إذا لم يتم العثور على المفتاح.
print(data.get('age')) # Outputs: None print(data.get('age', 'Unknown')) # Outputs: Unknown
بالنسبة للقواميس المتداخلة، فكر في استخدام الإفتراضي الافتراضي من وحدة المجموعات أو المكتبات مثل dotmap أو pydash.
from collections import defaultdict nested_data = defaultdict(lambda: 'Unknown') nested_data['name'] = 'Alice' print(nested_data['age']) # Outputs: Unknown
يمكن أن يؤدي الإفراط في استخدام كتل المحاولة باستثناء أو سوء استخدامها إلى حدوث أخطاء صامتة، حيث يتم اكتشاف الاستثناءات ولكن لا يتم التعامل معها بشكل صحيح. وهذا يمكن أن يجعل من الصعب اكتشاف الأخطاء وتصحيحها.
try: result = 1 / 0 except: pass # Silently ignores the error print("Continuing execution...")
في المثال أعلاه، تم اكتشاف خطأ ZeroDivisionError وتجاهله، ولكن هذا يمكن أن يخفي المشكلة الأساسية.
حدد دائمًا نوع الاستثناء الذي تلتقطه، وتعامل معه بشكل مناسب. يمكن أن يساعد تسجيل الخطأ أيضًا في تعقب المشكلات.
try: result = 1 / 0 except ZeroDivisionError as e: print(f"Error: {e}") print("Continuing execution...")
لمعالجة الاستثناءات على نطاق أوسع، يمكنك استخدام التسجيل بدلاً من المرور:
import logging try: result = 1 / 0 except Exception as e: logging.error(f"Unexpected error: {e}")
قبل بايثون 3، كانت عملية تقسيم عددين صحيحين تؤدي إلى تقسيم الأرضية افتراضيًا، مما يؤدي إلى اقتطاع النتيجة إلى عدد صحيح. على الرغم من أن Python 3 حلت هذه المشكلة من خلال التقسيم الحقيقي (/)، إلا أن بعض المطورين ما زالوا يواجهون مشكلات عند استخدام تقسيم الأرضية (//) عن غير قصد.
print(5 / 2) # Outputs: 2.5 in Python 3, but would be 2 in Python 2 print(5 // 2) # Outputs: 2
استخدم دائمًا / للتقسيم إلا إذا كنت بحاجة إلى تقسيم الأرضية على وجه التحديد. كن حذرًا عند نقل التعليمات البرمجية من Python 2 إلى Python 3.
print(5 / 2) # Outputs: 2.5 print(5 // 2) # Outputs: 2
للحصول على تعليمات برمجية واضحة ويمكن التنبؤ بها، فكر في استخدام العلامة العشرية.Decimal لإجراء عمليات حسابية أكثر دقة، خاصة في الحسابات المالية.
from decimal import Decimal print(Decimal('5') / Decimal('2')) # Outputs: 2.5
يتعامل جامع البيانات المهملة في بايثون مع معظم إدارة الذاكرة، ولكن المراجع الدائرية يمكن أن تسبب تسربًا للذاكرة إذا لم يتم التعامل معها بشكل صحيح. عندما يشير كائنان أو أكثر إلى بعضهما البعض، فقد لا يتم تجميع البيانات المهملة أبدًا، مما يؤدي إلى زيادة استخدام الذاكرة.
class Node: def __init__(self, value): self.value = value self.next = None node1 = Node(1) node2 = Node(2) node1.next = node2 node2.next = node1 # Circular reference del node1 del node2 # Memory not freed due to circular reference
لتجنب المراجع الدائرية، فكر في استخدام المراجع الضعيفة عبر وحدة Weakref، والتي تسمح بجمع المراجع المهملة في حالة عدم وجود مراجع قوية.
import weakref class Node: def __init__(self, value): self.value = value self.next = None node1 = Node(1) node2 = Node(2) node1.next = weakref.ref(node2) node2.next = weakref.ref(node1) # No circular reference now
بدلاً من ذلك، يمكنك كسر الدورة يدويًا عن طريق تعيين المراجع إلى لا شيء قبل حذف الكائنات.
node1.next = None node2.next = None del node1 del node2 # Memory is freed
حتى في عام 2024، سيستمر مطورو Python في مواجهة هذه الأخطاء الشائعة. على الرغم من تطور اللغة وتحسنها على مر السنين، غالبًا ما ترتبط هذه المشكلات بالجوانب الأساسية لكيفية عمل بايثون. من خلال فهم هذه المخاطر وتطبيق الحلول المناسبة، يمكنك كتابة تعليمات برمجية أكثر قوة وخالية من الأخطاء. برمجة سعيدة!
بقلم روبيش شارما المعروف أيضًا باسم @hackyrupesh
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3