التحقق من القيم الفارغة في بايثون: استخدام None وأفضل الممارسات

1. المقدمة

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

2. ما هو “null” في بايثون؟

تحتوي لغات البرمجة على قيمة خاصة تمثل غياب البيانات أو حالة غير صالحة. على سبيل المثال، تستخدم جافاسكريبت وجافا “null”، وتستخدم PHP “NULL”، لكن في بايثون تُسمى هذه القيمة “None“.

المفاهيم الأساسية لـ None في بايثون

None في بايثون تعادل “null” في اللغات الأخرى وتُشير إلى أن البيانات غير موجودة أو لم يتم تعيينها بشكل صريح. في بايثون، تُعامل جميع البيانات ككائنات، وNone ليست استثناءً — فهي كائن من النوع الخاص NoneType.
على سبيل المثال، من خلال تعيين None لمتغير كما هو موضح أدناه، تُشير إلى أنه لم يتم تعيين أي قيمة.

x = None

هذا يجعل من الواضح أن المتغير x لا يحمل قيمة مُعينة.

3. الاستخدام الأساسي لـ None

في بايثون، يُستخدم None في مواقف عديدة لتوضيح حالة معينة بشكل صريح. سنستعرض هنا الاستخدامات الأساسية لـ None.

تعيين None لمتغير

تعيين None لمتغير يعني أنه “لا يحتوي على قيمة” أوغير مُحدد”. يُستعمل ذلك للبيانات التي لم يتم اتخاذ قرار بشأنها بعد أو للمتغيرات التي تريد تركها فارغة مؤقتًا.

name = None
age = None

الدوال التي تُعيد None

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

def find_even_number(numbers):
    for num in numbers:
        if num % 2 == 0:
            return num
    return None

هذه الدالة تبحث وتُعيد عددًا زوجيًا، ولكن إذا لم يُعثر على أي عدد تُعيد None لتُشير إلى عدم وجود بيانات مطابقة.

4. كيفية تحديد None

في بايثون، الطريقة الشائعة للتحقق مما إذا كان المتغير يساوي None هي استخدام العامل is. على وجه الخصوص، يُعتبر العامل is موثوقًا جدًا لاختبار None ويوصى به في دليل أسلوب بايثون الرسمي (PEP 8). يمكن أيضًا استخدام العامل ==، لكن بما أنه يتصرف بشكل مختلف يجب الحذر. يوضح هذا القسم كل طريقة من طرق الاختبار.

كيفية الفحص باستخدام العامل is

العامل is هو الطريقة القياسية في بايثون للتحقق مما إذا كان المتغير يساوي None. يتحقق is من هوية الكائن، لذا فهو مناسب لتحديد None. لنلقِ نظرة على المثال التالي.

x = None
if x is None:
    print("x is None")

في هذا الكود، إذا كان المتغير x يساوي None، سيُطبع “x is None”. استخدام العامل is يجعل الكود أوضح وأسهل قراءة، لذا يُنصح باستخدامه لاختبار None بشكل خاص.

الاختلافات والتحذيرات عند استخدام العامل ==

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

x = None
if x == None:  # Works, but not recommended
    print("x is None")

فحص الحالة السلبية (is not)

إذا أردت التأكد من أن المتغير ليس None، استخدم العامل is not. يُعد is not ملائمًا لتحديد ما يجب فعله عندما لا يكون المتغير None.

x = 5
if x is not None:
    print("x is not None")

في هذا المثال، إذا كان x ليس None، سيُطبع “x is not None”. استخدام العامل is not بهذه الطريقة يتيح اختبارًا صريحًا للحالات التي لا يكون فيها المتغير None.

年収訴求

5. الفروقات بين None والقيم الزائفة الأخرى

في بايثون، هناك عدة قيم إلى جانب None تُقيم كـ “زائفة”. تشمل هذه السلسلة الفارغة ''، القيم العددية 0، القوائم الفارغة []، وهكذا. ومع ذلك، هذه القيم تختلف عن None. هنا سنعمق فهمنا للفروقات بين None والقيم الزائفة الأخرى.

نظرة عامة على None والقيم الزائفة الأخرى

القيم الأساسية التي تُقيم كزائفة في بايثون هي:

  • None
  • السلسلة الفارغة ''
  • العدد 0
  • القائمة الفارغة []
  • القاموس الفارغ {}

جميع هذه القيم تُقيم كـ False، لكن None، على عكسها، يمثل غياب القيمة.

الفروقات بين None والسلسلة الفارغة ''

السلسلة الفارغة '' تشير إلى أن البيانات فارغة مع الاحتفاظ بنوع البيانات str. من ناحية أخرى، None هو كائن خاص لا يمتلك نوعًا. لنلقِ نظرة على المثال التالي.

text = ''
if text is None:
    print("text is None")
elif text == '':
    print("text is an empty string")

هذا الكود يميز ما إذا كان text سلسلة فارغة أم None ويتعامل مع كل حالة وفقًا لذلك.

الفروقات عن العدد 0 والقائمة الفارغة []

العدد 0 والقائمة الفارغة [] أيضًا تُقيم كـ False، لكنهما تشير إلى وجود قيمة عددية أو قائمة محتواها فارغ. None، لعدم امتلاكه نوعًا، يعني أنه لم يتم تعيين شيء. لنؤكد ذلك بالمثال التالي.

data = 0
if data is None:
    print("data is None")
elif data == 0:
    print("data is 0")

فهم الفروقات بين None والقيم الزائفة الأخرى سيسمح بإجراء فحوصات أكثر دقة.

6. أمثلة عملية لاستخدام None

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

استخدام None كقيمة افتراضية للوسائط في الدالة

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

def greet(name=None):
    if name is None:
        print("Hello, Guest!")
    else:
        print(f"Hello, {name}!")

هذه الدالة greet تعرض “Hello, Guest!” عندما لا يتم توفير الوسيط name، وعند توفيره تُحيِّي باستخدام الاسم المحدد. من خلال الاستفادة من None بهذه الطريقة، يمكنك بسهولة إنشاء دوال ذات سلوك مرن.

معالجة None عند استرجاع البيانات من قاعدة بيانات

عند استرجاع البيانات من قاعدة بيانات، قد يتم إرجاع None عندما لا توجد بيانات. على سبيل المثال، تُعامل قيم NULL في SQL مباشرةً كـ None، وتقوم بإجراء فحوصات None لتحديد ما إذا كانت البيانات مفقودة.

user_data = get_user_data(user_id)  # Function to retrieve user data
if user_data is None:
    print("No user data found")
else:
    print("Displaying user data")

هنا، إذا لم تُرجع الدالة get_user_data بيانات المستخدم، يتم إرجاع None، وفي تلك الحالة تُعرض الرسالة “No user data found”. إجراء مثل هذه الفحوصات يجعل عمليات قاعدة البيانات أكثر أمانًا وموثوقية.

استخدام None في معالجة الأخطاء

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

def divide(a, b):
    if b == 0:
        return None
    return a / b

result = divide(10, 0)
if result is None:
    print("Error: Division by zero occurred")
else:
    print(f"Result: {result}")

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

7. أفضل الممارسات للتحقق من None

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

النهج الموصى به للتحقق من None بناءً على PEP 8

PEP 8، دليل الأسلوب الرسمي لبايثون، يوصي باستخدام عامل is للتحقق من None. هذا يجعل هوية الكائن المقصودة واضحة ويفصل None عن القيم الزائفة الأخرى.

value = None
if value is None:
    print("value is None")

استخدام is للتحقق من None يحسن القابلية للقراءة ويوضح النية، مما يساعد على منع الأخطاء.

أمثلة على الشيفرة لتحسين القابلية للقراءة والصيانة

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

# When no value is set, None is expected
data = fetch_data()
if data is None:
    print("Could not retrieve data")

بهذه الطريقة، توضيح معنى None عبر التعليقات يجعل صيانة الشيفرة المستقبلية أسهل.