أنواع البيانات
تعرّف على الأنواع الأساسية في بايثون ، int، float، str، bool ، وافهم ماذا يمثّل كلٌّ منها.
- التمييز بين قيم int و float و str و bool
- استخدام type() للتحقق من نوع القيمة
- فهم الكتابة الديناميكية في بايثون
- التعرّف على القيم الصادقة والكاذبة
المجموعة التي ينتمي إليها العدد
أجب عن سؤالين: معك تفاحات وقصصت واحدةً منها نصفين. هل تحمل الآن تفاحة بنفس معنى ما كنت تحمل ؟ نصف التفاحة ليس عددًا صحيحًا من التفاحات ، يعيش في ، ويعيش في .
يجيب العالم الرياضي بسؤال: إلى أي مجموعة ينتمي قيمةٌ ما؟ نفس التمييز يطارد كل برنامج: تخزّن الآلة بطريقةٍ تختلف عن ، وبطريقة تختلف عن "42". الكلمة التي تستعملها بايثون لسؤال «في أي مجموعة تعيش هذه القيمة» هي النوع.
إذن: كم مجموعةً تستحق التمييز؟ أربعٌ في البداية.
| النوع | ما هو، رياضيًّا | أمثلة |
|---|---|---|
int | ، الأعداد الصحيحة، مخزّنة بدقة تامة | 42, -7 |
float | ، مقرَّب بعددٍ ثابت من الأرقام الثنائية | 3.14, -0.5 |
str | متتالية منتهية من المحارف | "hello" |
bool | True, False |
سطر float يحمل تحفظًا مقصودًا ، مقرَّب. العدد الصحيح يُخزَّن بدقة في كل مرة. أما العدد الحقيقي فلا يكاد يُخزَّن بدقة أبدًا: كيف تخزّن بعددٍ منتهٍ من الأرقام؟ لا يمكنك، فتحتفظ بايثون بتقريبٍ منتهٍ وتتباعد الحسابات في الأرقام الأخيرة. هذه الحقيقة الواحدة تفسّر مفاجأةً شهيرة ستراها عن قريب.
سؤال المجموعة المنتمى إليها
أمام قيمةٍ ما، يمكنك أن تسأل عن نوعها مباشرة:
type(42) # <class 'int'>
type(3.14) # <class 'float'>
type("hi") # <class 'str'>
type(True) # <class 'bool'>ملاحظتان على الكتابة. أولًا، type(...) هي دالة ، تسلّمها قيمة فترجع لك كائن النوع الذي تنتمي إليه تلك القيمة. ثانيًا، يطبع الجواب <class 'int'>؛ وكلمة class هي مصطلح بايثون عن النوع، والكلمة بين علامتي الاقتباس هي اسم المجموعة. اقرأ <class 'float'> بمعنى «تنتمي إلى مجموعة float».
لا يلتزم الاسمُ بمجموعةٍ معيّنة
هنا تبدأ العوائد. في لغةٍ ذات كتابة ثابتة كنت ستصرّح مسبقًا: x عدد صحيح. أمّا بايثون فتدع الاسم يشير إلى حيث يشاء:
x = 5
print(type(x)) # <class 'int'>
x = "hello"
print(type(x)) # <class 'str'>إعادة توجيه اسمٍ نحو مجموعة أخرى أمرٌ جائز، فلا يُقرأ نوع x من أيّ تصريح ، بل بسؤاله إلى ماذا يشير حاليًا. هذا هو الكتابة الديناميكية. إنها مريحة، وهي أيضًا السبب في أن برنامجك قد يسلّم بصمتٍ نصًّا إلى دالةٍ تنتظر أرقامًا: لا شيء يمنع ذلك حتى تفشل العملية نفسها.
أيّ القيم تتصرف مثل True؟
كل قيمة صادقة أو كاذبة ، إمّا أن تتصرف مثل True في شرطٍ وإمّا مثل False. القاعدة مقتضبة جديرة بالتحقق:
- كاذبة: الصفر , والـ , والسلسلة الفارغة
"", وNone - صادقة: كل ما عدا ذلك
bool(0) # False
bool(1) # True
bool(-1) # True — أي عدد غير صفري صادق
bool("") # False
bool("hello") # True — أي سلسلة غير فارغة صادقةلاحظ ما هو مدرجٌ في القائمة وما استُبعد. -1 صادق؛ والصفر ليس كذلك. والسلسلة "0" صادقة ، إنها غير فارغة، ومعيار السلاسل هو خلوّها من المحارف لا قيمة محتواها. تدفع هذه القاعدة ثمنها في اللحظة التي تكتب فيها أوّل if: فالعبارة if score: تعني إذا لم تكن score صفرًا.
مثالٌ محلول: تدقيقُ تعبيرٍ
تدفعُ المجموعاتُ حين تمزجُها تعبيرًا. اقرأ الإيصالَ سطرًا سطرًا واسألْ مجموعةَ كلِّ نتيجةٍ:
unit_price = 4.75
quantity = 4
bill = unit_price * quantity # float: يبتلعُ العائمُ الصحيحَ
type(bill) # <class 'float'>
bool(bill) # True — كلُّ ما خالف الصفرَ صادقٌ
type(10 / 2) # <class 'float'> — لا تعودُ القسمةُ الحقيقيةُ صحيحًااقرأ bill حاصلَ مجموعتينِ مختلفتينِ. فالمجموعاتُ لا «تمتزج» ، يغلبُ float، لأن النسبةَ ليست عددًا صحيحًا لأيّ مقياسٍ، والمجموعةُ الأوسعُ يجب أن تحملَها. وعادةُ التدقيقِ سؤالُ المجموعةِ مباشرةً: يؤكد type(...) ما كنتَ تشكُّ فيه بدل الرهانِ على الحظِّ.
أخطاء شائعة
4 / 2يساوي2.0لا2. القسمة الحقيقية (/) ترجع دائمًا قيمةfloatفي بايثون 3 ، حتى حين تكون القسمة مضبوطة. للحصول على عدد صحيح اطلب القسمة الصحيحة:4 // 2←2.True + Trueيساوي2.boolفئة فرعية منintفي بايثون: يتصرفTrueمثل وFalseمثل في الحساب. تتداخل المجموعتان، لكنtype(True)يجيب دائمًا بـbool.type()تخبرك بالنوع الفعلي.type(True)هوboolلاint، مهما كانت راحةTrueفي الجمع.- يصف
type()الناتجَ لا المعاملاتِ.type(2 * 3.0)هوfloat، صحيحٌ مضروبٌ في عائمٍ يسكنُ مجموعةَ العائمِ. لا تتوقعْ من الأجزاءِ؛ اسألِ الجوابَ.
🧩 تحديات
🧩 تحدٍّ ، فكّر أولًا ثم أظهر
تنبّأ بـ type(7 / 2) ثم تحقّق.
💡 الجواب: type(7 / 2) هو float ، القسمة الحقيقية (/) تُنتج float دائمًا في بايثون 3، حتى لو كان المعاملان عددين صحيحين والناتج عددًا صحيحًا.
🧩 تحدٍّ ، فكّر أولًا ثم أظهر
تنبّأ بقيم bool(0) وbool(0.0) وbool("") وbool("0"). أيُّها صادقةٌ وأيُّها كاذبة؟
💡 الجواب: bool(0) ← False، bool(0.0) ← False، bool("") ← False (سلسلة فارغة)، bool("0") ← True (سلسلة غير فارغة، ولو كان محتواها المحرف «0»).
🧩 تحدٍّ ، فكّر أولًا ثم أظهر
في بايثون، 0.1 + 0.2 ليس مساويًا لـ 0.3. ها هي المسألة نفسها على الورق: ماذا يحدث عند تمثيل برقمَين عشريَّين؟ ثم اشرح لماذا لا يستطيع float ، الذي يقرّب بعددٍ منتهٍ من الأرقام الثنائية ، تمثيل بدقة.
💡 الجواب: برقمَين، يجب أن يصير $1/3$ هو $0.33$ ، خسارةٌ وقعت قبل أيّ عملية. كذلك لا يوجد لـ $0.1$ صورة ثنائية مضبوطة؛ يخزّن float قيمةً قريبة، وجمع قيمتين كهاتين يحمل أخطاءً يسيرة: يعطي 0.1 + 0.2 النتيجةَ 0.30000000000000004 لا 0.3. دقةٌ منتهية، لا خطأ بايثون.
🤔 أسئلة سقراطية
- إذا كان
bool(-1)هوTrue، فما القاعدة الواحدة التي تفسّر أن صادقٌ بينما كاذب؟ هل تعمّم القاعدة من الأعداد إلى السلاسل؟ - لدى بايثون
isinstance(42, int)التي ترجعTrue. هل تكونisinstanceأوثق منtype(x) == intفي فحص الأنواع؟ ولماذا؟ - لماذا تكتب بايثون
TrueوFalseبحروفٍ كبيرة بدلًا منtrueوfalse؟ وما الكلمات الكبيرة الأخرى التي تحجزها بايثون؟
✅ فحص سريع
١. ما نوع القيمة 3.14؟
٢. ما نتيجة True + True؟
٣. أيُّ من هذه القيم كاذبة؟