لماذا تهمّ الأنواع أصلاً؟
النوع (type) هو ببساطة تصنيف يُخبر بايثون كيف ينبغي أن يتصرّف كل قيمة. جمع عددين صحيحين يعني عملية حسابية، بينما جمع نصّين يعني دمجهما معاً، أمّا جمع نصّ مع عدد فهو خطأ. باختصار، نوع القيمة هو ما يُحدّد العمليات المنطقية التي يمكن تطبيقها عليها.
توفّر بايثون مجموعة صغيرة ومألوفة من أنواع البيانات المدمجة. هناك أربعة منها ستستخدمها في كل برنامج تقريباً: int و float و str و bool. أمّا البقية فستظهر لك حين تبدأ بتنظيم بياناتك داخل مجموعات وهياكل أكبر.
الأرقام: int و float
في بايثون نوعان من الأرقام، وهي تختار لك النوع المناسب تلقائياً بناءً على طريقة كتابتك للقيمة:
ما فيه فاصلة عشرية؟ يكون الناتج من نوع int. فيه فاصلة عشرية؟ النتيجة ستكون float. وعند إجراء العمليات الحسابية، يمكن خلط النوعين بكل حرية، فأي عملية تتضمن float سينتج عنها قيمة float:
يمكن للأعداد الصحيحة في بايثون أن تكبر بقدر ما تسمح به ذاكرتك — لا يوجد overflow، ولا سقف ثابت عند 32 أو 64 بت. جرّب أن تحسب 2 ** 1000 وسيُرجع لك بايثون كل رقم من أرقامه كاملةً.
أما الأعداد العشرية فتتبع قواعد IEEE 754 المعتادة، وهذا يعني بعض المفاجآت الكلاسيكية:
ستطبع لك 0.30000000000000004 بدل 0.3. هذه ليست مشكلة في بايثون، بل هكذا تعمل الأعداد العشرية الثنائية (binary floating point) في كل لغات البرمجة. لو احتجت دقة تامة في الأرقام العشرية (مثلاً في التعاملات المالية)، استخدم وحدة decimal. أما في بقية الحالات، فيكفي تقريب الرقم عند عرضه.
النصوص: نوع البيانات str
النصوص (strings) عبارة عن سلسلة من المحارف. ضعها بين علامتَي اقتباس مفردتَين أو مزدوجتَين، فبايثون لا يهمّها أيّهما تختار طالما أن علامة البداية تطابق علامة النهاية:
السلاسل النصية المُحاطة بثلاث علامات اقتباس (""" ... """) تمتد على أكثر من سطر:
للنصوص مكتبة ضخمة ستتعلمها مع الوقت — التقطيع (slicing)، ودوال مثل .upper() و .split() و .replace()، بالإضافة إلى تنسيق الـ f-string الذي يتيح لك كتابة f"Hello, {name}". سنخصص صفحة كاملة للنصوص لاحقًا.
القيم المنطقية: bool
نوع بيانات بقيمتين فقط، وتُكتبان بالضبط كما ترى هنا — True و False، مع حرف كبير في البداية. وعمليات المقارنة تُنتج قيمًا منطقية:
تحت الغطاء، القيمتان True و False هما في الحقيقة 1 و 0، وهذا يعني أنه يمكنك جمع القيم المنطقية مباشرة لو احتجت يومًا أن تعرف كم شرطًا تحقق:
None: غياب القيمة
None هي طريقة بايثون للتعبير عن "لا توجد قيمة". فالدوال التي لا تُرجع شيئًا بشكل صريح تُعيد None تلقائيًا. كما تُستخدم غالبًا كقيمة مبدئية أو عنصر نائب:
العُرف هو استخدام is None و is not None في الاختبارات، وليس == None. لأن is يفحص الهوية (identity)، وهذا هو المعنى الفعلي الذي تقصده هنا.
القوائم والصفوف والمجموعات والقواميس
هذه هي أنواع المجموعات الأربعة المدمجة في بايثون. كل نوع منها له صفحة مخصصة تشرحه بالتفصيل، لكن إليك لمحة سريعة حتى تتعرّف عليها:
قواعد عامة تختار على أساسها:
- List: تسلسل تتوقع أنه هيتغير. إضافة عناصر، حذفها، ترتيبها — كله عادي.
- Tuple: تسلسل عايز تحميه من التغيير. بيُستخدم كتير مع السجلات ذات الشكل الثابت زي إحداثيات
(x, y). - Set: مجموعة من العناصر الفريدة، لما وجود تكرار يكون مشكلة.
- Dict: بحث بالمفتاح. هي البنية اللي بتشبه JSON.
التحويل بين الأنواع في بايثون
بايثون مش هتحوّل الأنواع نيابة عنك تلقائيًا لو كان ده فيه مخاطرة. لو عايز تحوّل عدد صحيح لنص، أو نص لرقم، لازم تطلب ده بنفسك صراحة:
لو كان التحويل غير منطقي — مثل int("hello") — فإن بايثون يرفع استثناء ValueError ويخبرك بالقيمة التي أعطيتها له. خطأ واضح، تفهم سببه، تصلحه، وتكمل طريقك.
كيفية التحقق من نوع البيانات في بايثون
هناك أداتان تستحقان المعرفة:
الدالة type() ممتازة لإلقاء نظرة سريعة داخل الـ REPL، أما isinstance() فهي الخيار الصحيح في الكود الحقيقي، لأنها تتعامل بشكل سليم مع الوراثة وتتيح لك التحقق من عدة أنواع دفعة واحدة.
تمرين استكشافي سريع
جرّب تشغيل الكتلة التالية كما هي، ثم غيّر بعض القيم ولاحظ كيف تتبدّل الأنواع:
لا يلزمك فهم حلقة for الآن — سنصل إليها لاحقاً — لكن هذا يعطيك لمحة سريعة عن أنواع البيانات المدمجة في بايثون دفعة واحدة.
اختر نوع البيانات المناسب لبياناتك
لا داعي لحفظ كل نوع من أنواع البيانات في بايثون الآن. ما يهم فعلاً هو أن تتعرف على النوع حين تراه، وأن تختار النوع الصحيح عند إنشاء بياناتك. اسأل نفسك: "هل هذه البيانات ثابتة أم متغيرة؟ فريدة أم مكررة؟ هل سأصل إليها عن طريق مفتاح أم عن طريق موقعها؟" هذه الأسئلة الأربعة تحسم اختيار نوع المجموعة في 90% من الحالات.
في الفصل التالي: نتعمق في السلاسل النصية (strings)، فهي نوع البيانات الذي ستتعامل معه في كل برنامج تقريباً.
الأسئلة الشائعة
ما هي أنواع البيانات الأساسية في بايثون؟
الأعداد (int و float)، النصوص (str)، القيم المنطقية (bool)، القيمة None، بالإضافة إلى أربعة أنواع للمجموعات هي: list و tuple و set و dict. معظم ما تراه في أكواد بايثون مبني على هذه الأنواع، مع بعض الأنواع الإضافية مثل bytes و complex و frozenset.
كيف أعرف نوع قيمة معينة في بايثون؟
استخدم الدالة type()؛ فمثلاً type(42) ترجع <class 'int'>، و type('hi') ترجع <class 'str'>. أما إذا أردت فحصاً منطقياً يعطيك True أو False فاستعمل isinstance(value, int)، وهو أفضل لأنه يتعامل مع الفئات الفرعية أيضاً.
هل بايثون لغة ذات تنميط ثابت أم ديناميكي؟
بايثون لغة ذات تنميط ديناميكي (Dynamically typed)؛ أي أن المتغير يمكن أن يشير إلى أي نوع من القيم، ويمكن أن يتغير نوعه خلال تنفيذ البرنامج. هذا يختلف عن لغات مثل Java أو C++ التي تُجبرك على تحديد نوع المتغير مسبقاً دون إمكانية تغييره.