PyDA Course
📖 درس 3 مبتدئ ⏱ 15 دقيقة ⚡ +10 XP ColabKagglenbviewerBinderDeepnoteGitHub types · int · float · str · bool · dynamic-typing

أنواع البيانات

تعرّف على الأنواع الأساسية في بايثون ، int، float، str، bool ، وافهم ماذا يمثّل كلٌّ منها.

🎯 ماذا ستتعلم:
  • التمييز بين قيم int و float و str و bool
  • استخدام type() للتحقق من نوع القيمة
  • فهم الكتابة الديناميكية في بايثون
  • التعرّف على القيم الصادقة والكاذبة

المجموعة التي ينتمي إليها العدد

أجب عن سؤالين: معك 77 تفاحات وقصصت واحدةً منها نصفين. هل تحمل الآن 7+127 + \frac{1}{2} تفاحة بنفس معنى ما كنت تحمل 77؟ نصف التفاحة ليس عددًا صحيحًا من التفاحات ، يعيش 77 في Z\mathbb{Z}، ويعيش 7127\frac{1}{2} في Q\mathbb{Q}.

يجيب العالم الرياضي بسؤال: إلى أي مجموعة ينتمي قيمةٌ ما؟ نفس التمييز يطارد كل برنامج: تخزّن الآلة 4242 بطريقةٍ تختلف عن 42.542.5، وبطريقة تختلف عن "42". الكلمة التي تستعملها بايثون لسؤال «في أي مجموعة تعيش هذه القيمة» هي النوع.

إذن: كم مجموعةً تستحق التمييز؟ أربعٌ في البداية.

النوعما هو، رياضيًّاأمثلة
intZ\mathbb{Z} ، الأعداد الصحيحة، مخزّنة بدقة تامة42, -7
floatR\mathbb{R}، مقرَّب بعددٍ ثابت من الأرقام الثنائية3.14, -0.5
strمتتالية منتهية من المحارف"hello"
bool{True,False}\{\text{True}, \text{False}\}True, False

سطر float يحمل تحفظًا مقصودًا ، مقرَّب. العدد الصحيح يُخزَّن بدقة في كل مرة. أما العدد الحقيقي فلا يكاد يُخزَّن بدقة أبدًا: كيف تخزّن 1/3=0.3331/3 = 0.333\ldots بعددٍ منتهٍ من الأرقام؟ لا يمكنك، فتحتفظ بايثون بتقريبٍ منتهٍ وتتباعد الحسابات في الأرقام الأخيرة. هذه الحقيقة الواحدة تفسّر مفاجأةً شهيرة ستراها عن قريب.

سؤال المجموعة المنتمى إليها

أمام قيمةٍ ما، يمكنك أن تسأل عن نوعها مباشرة:

python
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 عدد صحيح. أمّا بايثون فتدع الاسم يشير إلى حيث يشاء:

python
x = 5
print(type(x))    # <class 'int'>
x = "hello"
print(type(x))    # <class 'str'>

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

أيّ القيم تتصرف مثل True؟

كل قيمة صادقة أو كاذبة ، إمّا أن تتصرف مثل True في شرطٍ وإمّا مثل False. القاعدة مقتضبة جديرة بالتحقق:

  • كاذبة: الصفر 00, والـ 0.00.0, والسلسلة الفارغة "", وNone
  • صادقة: كل ما عدا ذلك
python
bool(0)         # False
bool(1)         # True
bool(-1)        # True   — أي عدد غير صفري صادق
bool("")        # False
bool("hello")   # True   — أي سلسلة غير فارغة صادقة

لاحظ ما هو مدرجٌ في القائمة وما استُبعد. -1 صادق؛ والصفر ليس كذلك. والسلسلة "0" صادقة ، إنها غير فارغة، ومعيار السلاسل هو خلوّها من المحارف لا قيمة محتواها. تدفع هذه القاعدة ثمنها في اللحظة التي تكتب فيها أوّل if: فالعبارة if score: تعني إذا لم تكن score صفرًا.

مثالٌ محلول: تدقيقُ تعبيرٍ

تدفعُ المجموعاتُ حين تمزجُها تعبيرًا. اقرأ الإيصالَ سطرًا سطرًا واسألْ مجموعةَ كلِّ نتيجةٍ:

python
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 // 22.
  • True + True يساوي 2. bool فئة فرعية من int في بايثون: يتصرف True مثل 11 وFalse مثل 00 في الحساب. تتداخل المجموعتان، لكن 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. ها هي المسألة نفسها على الورق: ماذا يحدث عند تمثيل 1/3=0.3331/3 = 0.333\ldots برقمَين عشريَّين؟ ثم اشرح لماذا لا يستطيع float ، الذي يقرّب R\mathbb{R} بعددٍ منتهٍ من الأرقام الثنائية ، تمثيل 0.10.1 بدقة.

💡 الجواب: برقمَين، يجب أن يصير $1/3$ هو $0.33$ ، خسارةٌ وقعت قبل أيّ عملية. كذلك لا يوجد لـ $0.1$ صورة ثنائية مضبوطة؛ يخزّن float قيمةً قريبة، وجمع قيمتين كهاتين يحمل أخطاءً يسيرة: يعطي 0.1 + 0.2 النتيجةَ 0.30000000000000004 لا 0.3. دقةٌ منتهية، لا خطأ بايثون.

🤔 أسئلة سقراطية

  • إذا كان bool(-1) هو True، فما القاعدة الواحدة التي تفسّر أن 1-1 صادقٌ بينما 00 كاذب؟ هل تعمّم القاعدة من الأعداد إلى السلاسل؟
  • لدى بايثون isinstance(42, int) التي ترجع True. هل تكون isinstance أوثق من type(x) == int في فحص الأنواع؟ ولماذا؟
  • لماذا تكتب بايثون True وFalse بحروفٍ كبيرة بدلًا من true وfalse؟ وما الكلمات الكبيرة الأخرى التي تحجزها بايثون؟

✅ فحص سريع

١. ما نوع القيمة 3.14؟

٢. ما نتيجة True + True؟

٣. أيُّ من هذه القيم كاذبة؟

typesintfloatstrbooldynamic-typing