التحويل بين أنواع البيانات (Type Casting)
التحويل بين أنواع البيانات (Type Casting أو Type Conversion) هو عملية تحويل قيمة من نوع بيانات إلى نوع آخر. على سبيل المثال، تحويل نص "25" إلى رقم صحيح 25، أو تحويل رقم عشري 3.14 إلى نص "3.14". هذه العملية ضرورية جداً في البرمجة لأنك غالباً ستحتاج للتعامل مع بيانات من مصادر مختلفة (إدخال المستخدم، ملفات، قواعد بيانات) وتحويلها للنوع المناسب لمعالجتها. في هذا الدرس الشامل، سنتعلم كل طرق التحويل بين الأنواع في بايثون، متى نستخدمها، وكيف نتعامل مع الأخطاء التي قد تحدث أثناء التحويل.
1. لماذا نحتاج للتحويل بين الأنواع؟
تخيل أنك تكتب برنامجاً يطلب من المستخدم إدخال عمره، ثم يحسب كم سنة تبقى له حتى التقاعد. عندما يُدخل المستخدم "25" من لوحة المفاتيح، بايثون تستقبلها كنص (String) وليس كرقم. لو حاولت طرح هذا النص من رقم، ستحصل على خطأ:
# مثال يوضح المشكلة
age_text = "25" # هذا نص، ليس رقماً
retirement_age = 65
# ❌ هذا سيسبب خطأ TypeError
# years_left = retirement_age - age_text
# ✅ الحل: تحويل النص إلى رقم
age_number = int(age_text) # تحويل النص إلى رقم صحيح
years_left = retirement_age - age_number
print(f"العمر: {age_number}")
print(f"سنوات متبقية للتقاعد: {years_left}")
التحويل بين الأنواع ضروري في حالات كثيرة:
- قراءة إدخال المستخدم (دائماً يكون نصاً)
- قراءة البيانات من ملفات (عادة تكون نصوصاً)
- إجراء عمليات حسابية على بيانات نصية
- عرض الأرقام كنصوص في رسائل مخصصة
- التحقق من الشروط المنطقية
2. التحويل إلى رقم صحيح (int)
دالة int() تحول القيمة إلى رقم صحيح (Integer). يمكنها تحويل النصوص، الأرقام العشرية، والقيم المنطقية:
# تحويل نص إلى رقم صحيح
text_number = "100"
number = int(text_number)
print(f"'{text_number}' (نص) → {number} (رقم)")
print(f"النوع: {type(text_number)} → {type(number)}")
# تحويل رقم عشري إلى رقم صحيح (يحذف الكسر العشري)
decimal = 3.99
integer = int(decimal)
print(f"\n{decimal} → {integer} (تم حذف الكسر العشري)")
# تحويل رقم سالب
negative_text = "-50"
negative_num = int(negative_text)
print(f"\n'{negative_text}' → {negative_num}")
# تحويل قيم منطقية
print(f"\nTrue → {int(True)}") # True = 1
print(f"False → {int(False)}") # False = 0
# أمثلة عملية
price_text = "1500"
discount_text = "200"
final_price = int(price_text) - int(discount_text)
print(f"\nالسعر بعد الخصم: {final_price} دولار")
⚠️ أخطاء شائعة عند التحويل إلى int
# ❌ لا يمكن تحويل نص يحتوي على كسر عشري مباشرة
# number = int("3.14") # ValueError
# ✅ الحل: حوّل إلى float أولاً، ثم إلى int
number = int(float("3.14"))
print(f"'3.14' → {number}")
# ❌ لا يمكن تحويل نص لا يمثل رقماً
# number = int("hello") # ValueError
# ✅ الحل: التحقق قبل التحويل
text = "hello"
if text.isdigit():
number = int(text)
else:
print(f"'{text}' ليس رقماً صحيحاً")
# ❌ لا يمكن تحويل نص فارغ
# number = int("") # ValueError
# ✅ الحل: التحقق من عدم فراغ النص
text = ""
if text:
number = int(text)
else:
print("النص فارغ، لا يمكن التحويل")
3. التحويل إلى رقم عشري (float)
دالة float() تحول القيمة إلى رقم عشري (Floating-Point Number):
# تحويل نص إلى رقم عشري
price_text = "99.99"
price = float(price_text)
print(f"'{price_text}' → {price}")
print(f"النوع: {type(price)}")
# تحويل رقم صحيح إلى رقم عشري
integer = 42
decimal = float(integer)
print(f"\n{integer} → {decimal}")
# تحويل نص رقم صحيح إلى float
whole_number = "100"
result = float(whole_number)
print(f"\n'{whole_number}' → {result}")
# تحويل قيم منطقية
print(f"\nTrue → {float(True)}") # 1.0
print(f"False → {float(False)}") # 0.0
# مثال عملي: حساب المعدل
grade1 = "85"
grade2 = "90"
grade3 = "78"
average = (float(grade1) + float(grade2) + float(grade3)) / 3
print(f"\nالمعدل: {average:.2f}")
# التعامل مع الترميز العلمي
scientific = "1.5e3" # 1.5 × 10³ = 1500
number = float(scientific)
print(f"\n'{scientific}' → {number}")
4. التحويل إلى نص (str)
دالة str() تحول أي قيمة إلى نص (String). هذه الدالة نادراً ما تفشل لأن كل شيء يمكن تمثيله كنص:
# تحويل رقم صحيح إلى نص
age = 25
age_text = str(age)
print(f"{age} → '{age_text}'")
print(f"النوع: {type(age)} → {type(age_text)}")
# تحويل رقم عشري إلى نص
pi = 3.14159
pi_text = str(pi)
print(f"\n{pi} → '{pi_text}'")
# تحويل قيمة منطقية إلى نص
is_active = True
status = str(is_active)
print(f"\n{is_active} → '{status}'")
# مثال عملي: دمج نصوص وأرقام
name = "أحمد"
age = 25
score = 95.5
# ❌ هذا سيسبب خطأ (لا يمكن دمج نص ورقم مباشرة)
# message = "الاسم: " + name + ", العمر: " + age
# ✅ الحل 1: تحويل الأرقام إلى نصوص
message = "الاسم: " + name + ", العمر: " + str(age) + ", الدرجة: " + str(score)
print(f"\n{message}")
# ✅ الحل 2: استخدام f-strings (الطريقة الأفضل)
message = f"الاسم: {name}, العمر: {age}, الدرجة: {score}"
print(message)
# تحويل قوائم وقواميس إلى نصوص
numbers = [1, 2, 3, 4, 5]
numbers_text = str(numbers)
print(f"\n{numbers} → '{numbers_text}'")
5. التحويل إلى قيمة منطقية (bool)
دالة bool() تحول القيمة إلى قيمة منطقية (True أو False). القاعدة العامة: القيم "الفارغة" أو "الصفرية" تُحوّل إلى False، وكل شيء آخر يُحوّل إلى True:
# القيم التي تُحوّل إلى False
print("القيم التي تُعتبر False:")
print(f" bool(0) = {bool(0)}")
print(f" bool(0.0) = {bool(0.0)}")
print(f" bool('') = {bool('')}")
print(f" bool([]) = {bool([])}")
print(f" bool({{}}) = {bool({})}")
print(f" bool(None) = {bool(None)}")
print("\nالقيم التي تُعتبر True:")
print(f" bool(1) = {bool(1)}")
print(f" bool(-1) = {bool(-1)}")
print(f" bool(3.14) = {bool(3.14)}")
print(f" bool('hello') = {bool('hello')}")
print(f" bool([1, 2]) = {bool([1, 2])}")
print(f" bool(' ') = {bool(' ')}") # مسافة واحدة ليست فارغة!
# مثال عملي: التحقق من وجود بيانات
username = input("أدخل اسم المستخدم: ")
if bool(username): # أو ببساطة: if username:
print(f"مرحباً {username}!")
else:
print("لم تُدخل اسماً!")
# مثال آخر: التحقق من رصيد الحساب
balance = 0
if bool(balance):
print(f"رصيدك: {balance} دولار")
else:
print("رصيدك فارغ!")
# استخدام في الشروط
items_count = 5
if items_count: # تلقائياً يُحوّل إلى bool
print(f"لديك {items_count} عناصر")
else:
print("لا توجد عناصر")
6. التحويل الضمني vs الصريح
هناك نوعان من التحويل بين الأنواع:
التحويل الضمني (Implicit Conversion)
بايثون تقوم به تلقائياً عند الحاجة، دون أن تطلب منها ذلك:
# التحويل الضمني من int إلى float
x = 10 # int
y = 3.5 # float
result = x + y # بايثون تحول x إلى float تلقائياً
print(f"{x} + {y} = {result}")
print(f"نوع النتيجة: {type(result)}")
# مثال آخر
a = 5 # int
b = 2.0 # float
c = a * b # النتيجة ستكون float
print(f"\n{a} × {b} = {c}")
print(f"نوع النتيجة: {type(c)}")
التحويل الصريح (Explicit Conversion)
أنت تطلب التحويل بشكل واضح باستخدام دوال مثل int() و float() و str():
# التحويل الصريح
text = "100"
number = int(text) # تحويل صريح من str إلى int
print(f"'{text}' (نص) → {number} (رقم)")
# مثال: قراءة إدخال المستخدم
age_input = input("أدخل عمرك: ") # input() تُرجع دائماً str
age = int(age_input) # تحويل صريح ضروري
print(f"عمرك: {age} سنة")
print(f"بعد 10 سنوات ستكون: {age + 10}")
7. معالجة أخطاء التحويل
عند تحويل بيانات من مصادر خارجية (إدخال المستخدم، ملفات)، قد تحدث أخطاء. يجب معالجتها بشكل صحيح:
# معالجة أخطاء التحويل باستخدام try-except
def safe_int_conversion(text):
"""تحويل آمن من نص إلى رقم صحيح"""
try:
return int(text)
except ValueError:
print(f"خطأ: '{text}' ليس رقماً صحيحاً")
return None
# اختبار الدالة
print("اختبار التحويل الآمن:")
print(f"'123' → {safe_int_conversion('123')}")
print(f"'hello' → {safe_int_conversion('hello')}")
print(f"'3.14' → {safe_int_conversion('3.14')}")
# مثال عملي: حاسبة آمنة
print("\n--- حاسبة بسيطة ---")
num1_text = input("أدخل الرقم الأول: ")
num2_text = input("أدخل الرقم الثاني: ")
try:
num1 = float(num1_text)
num2 = float(num2_text)
result = num1 + num2
print(f"\nالنتيجة: {num1} + {num2} = {result}")
except ValueError:
print("\nخطأ: الرجاء إدخال أرقام صحيحة!")
# دالة متقدمة للتحويل مع قيمة افتراضية
def convert_to_int(text, default=0):
"""تحويل إلى int مع قيمة افتراضية عند الفشل"""
try:
return int(text)
except (ValueError, TypeError):
return default
# اختبار
print(f"\nتحويل مع قيمة افتراضية:")
print(f"'50' → {convert_to_int('50')}")
print(f"'abc' → {convert_to_int('abc', default=0)}")
print(f"None → {convert_to_int(None, default=-1)}")
8. مثال شامل: نظام تسجيل طالب
لنجمع كل ما تعلمناه في مثال عملي واقعي:
"""
نظام تسجيل طالب - يوضح استخدام Type Casting
"""
print("=" * 60)
print("نظام تسجيل الطلاب".center(60))
print("=" * 60)
print()
# جمع البيانات (كلها تأتي كنصوص من input)
name = input("الاسم الكامل: ")
age_text = input("العمر: ")
grade1_text = input("درجة المادة الأولى: ")
grade2_text = input("درجة المادة الثانية: ")
grade3_text = input("درجة المادة الثالثة: ")
is_active_text = input("نشط؟ (yes/no): ")
print("\n" + "=" * 60)
print("معالجة البيانات...".center(60))
print("=" * 60)
# التحويل مع معالجة الأخطاء
try:
# تحويل العمر إلى رقم صحيح
age = int(age_text)
# تحويل الدرجات إلى أرقام عشرية
grade1 = float(grade1_text)
grade2 = float(grade2_text)
grade3 = float(grade3_text)
# تحويل الحالة إلى قيمة منطقية
is_active = is_active_text.lower() in ['yes', 'y', 'نعم']
# حساب المعدل
average = (grade1 + grade2 + grade3) / 3
# تحديد التقدير
if average >= 90:
grade_letter = "A"
grade_text = "ممتاز"
elif average >= 80:
grade_letter = "B"
grade_text = "جيد جداً"
elif average >= 70:
grade_letter = "C"
grade_text = "جيد"
elif average >= 60:
grade_letter = "D"
grade_text = "مقبول"
else:
grade_letter = "F"
grade_text = "راسب"
# عرض التقرير
print("\n" + "=" * 60)
print("تقرير الطالب".center(60))
print("=" * 60)
print()
print(f"الاسم: {name}")
print(f"العمر: {age} سنة")
print(f"الحالة: {'نشط ✓' if is_active else 'غير نشط ✗'}")
print()
print("الدرجات:")
print(f" المادة الأولى: {grade1:.2f}")
print(f" المادة الثانية: {grade2:.2f}")
print(f" المادة الثالثة: {grade3:.2f}")
print(f" {'─' * 25}")
print(f" المعدل: {average:.2f}")
print()
print(f"التقدير: {grade_letter} ({grade_text})")
print()
# معلومات إضافية باستخدام التحويلات
years_to_graduation = 4 - (age - 18) # افتراض دخول الجامعة في 18
if years_to_graduation > 0:
print(f"سنوات متبقية للتخرج (تقديرياً): {years_to_graduation}")
print()
print("=" * 60)
print("تم التسجيل بنجاح!".center(60))
print("=" * 60)
# عرض أنواع البيانات المستخدمة
print("\nملخص أنواع البيانات:")
print(f" name: {type(name).__name__}")
print(f" age: {type(age).__name__}")
print(f" grade1: {type(grade1).__name__}")
print(f" average: {type(average).__name__}")
print(f" is_active: {type(is_active).__name__}")
except ValueError as e:
print("\n❌ خطأ في البيانات المدخلة!")
print("الرجاء التأكد من:")
print(" - العمر رقم صحيح")
print(" - الدرجات أرقام (يمكن أن تكون عشرية)")
print(f"\nتفاصيل الخطأ: {e}")
💡 نصائح مهمة
- استخدم
int()للأرقام الصحيحة فقط - استخدم
float()للأرقام التي قد تحتوي على كسور عشرية - استخدم
str()عند دمج نصوص وأرقام - دائماً استخدم
try-exceptعند تحويل بيانات من مصادر خارجية - تذكر:
int(3.99)يعطي 3 (يحذف الكسر، لا يُقرّب) - للتقريب، استخدم
round()بدلاً منint()
الخطوة التالية
الآن بعد أن أتقنت التحويل بين الأنواع، حان وقت تعلم العمليات الحسابية
الدرس التالي: العمليات الحسابية في Python