مرحبًا بك في درس جديد من سلسلة مشكلة وحل على موقع بايثون العرب. في هذا المقال سنشرح واحدًا من أكثر أخطاء بايثون ظهورًا للمبتدئين، وهو خطأ:
ValueError: invalid literal for int() with base 10
غالبًا يظهر هذا الخطأ عندما تستخدم الدالة int() لتحويل قيمة إلى عدد صحيح، لكن القيمة التي تحاول تحويلها ليست رقمًا صحيحًا صالحًا. ويظهر كثيرًا عند استخدام input()؛ لأن إدخال المستخدم يأتي كنص دائمًا، حتى لو كتب المستخدم رقمًا.
في هذا الدرس سنفهم معنى الخطأ، ولماذا يحدث، وكيف تحله باستخدام try except، ومتى تستخدم int() ومتى تستخدم float()، وكيف تجعل برنامجك يتعامل مع إدخال المستخدم بطريقة آمنة وواضحة.
{getToc} $title={محتوى المقال}
{alertInfo} إذا كنت جديدًا في التعامل مع الإدخال والتحويل بين الأنواع، راجع درس أنواع البيانات في Python ودرس معرفة هل الرقم زوجي أم فردي في Python.
قصة المشكلة
تخيل أنك تكتب برنامجًا بسيطًا يطلب من المستخدم إدخال عمره، ثم يحول الإدخال إلى رقم باستخدام int():
age = int(input("أدخل عمرك: "))
print("عمرك هو:", age)
إذا كتب المستخدم:
25
سيعمل البرنامج بدون مشكلة. لكن إذا كتب المستخدم كلمة مثل:
hello
سيظهر الخطأ:
ValueError: invalid literal for int() with base 10: 'hello'
السبب أن بايثون لا يستطيع تحويل كلمة hello إلى عدد صحيح.
ما معنى ValueError في Python؟
خطأ ValueError يعني أن نوع العملية أو الدالة التي استخدمتها صحيح، لكن القيمة التي أرسلتها لهذه الدالة غير مناسبة.
بمعنى أبسط: الدالة int() تعرف كيف تحول النصوص الرقمية إلى أرقام، لكنها لا تستطيع تحويل أي نص عشوائي إلى رقم.
هذا صحيح:
int("10")
لأن النص "10" يحتوي على رقم صحيح.
أما هذا غير صحيح:
int("hello")
لأن كلمة "hello" ليست رقمًا، لذلك يظهر خطأ ValueError.
{alertSuccess} الخلاصة البسيطة: int() لا تقبل إلا قيمة يمكن فهمها كعدد صحيح، مثل "10" أو "-5"، لكنها لا تقبل "hello" أو "12.5" أو قيمة فارغة.
سبب ظهور خطأ invalid literal for int
سبب الخطأ هو محاولة تحويل قيمة غير صالحة إلى عدد صحيح باستخدام int().
هذه أمثلة تسبب الخطأ:
int("abc")
int("12.5")
int("")
int("10 years")
كل هذه القيم لا تصلح للتحويل المباشر إلى عدد صحيح:
"abc"نص وليس رقمًا."12.5"رقم عشري وليس عددًا صحيحًا بصيغة مناسبة لـint()مباشرة من النص.""قيمة فارغة."10 years"تحتوي على رقم وكلمة معًا.
لماذا يحدث الخطأ كثيرًا مع input؟
الدالة input() في بايثون ترجع القيمة كنص دائمًا. وهذا يعني أن المستخدم إذا كتب الرقم 10، فإن بايثون تستقبله كأنه النص "10" وليس الرقم 10.
جرّب هذا المثال:
number = input("أدخل رقمًا: ")
print(type(number))
حتى لو أدخل المستخدم 10، سيكون النوع:
<class 'str'>
لذلك نحتاج إلى تحويله:
number = int(input("أدخل رقمًا: "))
لكن هنا تظهر المشكلة: إذا لم يدخل المستخدم رقمًا صحيحًا، ستفشل عملية التحويل ويظهر الخطأ.
الحل الأول: استخدام try except
أفضل حل عملي للتعامل مع هذا الخطأ هو استخدام try except. بهذه الطريقة، نجرب تحويل الإدخال إلى رقم، وإذا حدث خطأ نعرض رسالة مفهومة بدل أن يتوقف البرنامج.
try:
age = int(input("أدخل عمرك: "))
print("عمرك هو:", age)
except ValueError:
print("خطأ: الرجاء إدخال رقم صحيح فقط")
الآن إذا كتب المستخدم 25 سيعمل البرنامج، وإذا كتب hello ستظهر رسالة واضحة بدل ظهور رسالة خطأ طويلة.
شرح try except ببساطة
الكود داخل try هو الكود الذي قد يسبب خطأ:
try:
age = int(input("أدخل عمرك: "))
إذا نجح التحويل، يكمل البرنامج بشكل طبيعي. وإذا حدث خطأ من نوع ValueError، ينتقل البرنامج إلى جزء except:
except ValueError:
print("خطأ: الرجاء إدخال رقم صحيح فقط")
بهذا الشكل يصبح البرنامج أفضل للمستخدم؛ لأنه لا يتوقف فجأة ولا يعرض رسالة خطأ مربكة.
{alertInfo} استخدم try except عندما تتعامل مع إدخال المستخدم، لأنك لا تستطيع ضمان أن المستخدم سيكتب القيمة بالشكل الصحيح دائمًا.
الحل الثاني: استخدام isdigit قبل int
يمكنك أيضًا استخدام isdigit() للتأكد من أن النص يحتوي على أرقام فقط قبل تحويله إلى عدد صحيح.
user_input = input("أدخل رقمًا: ")
if user_input.isdigit():
number = int(user_input)
print("الرقم هو:", number)
else:
print("الرجاء إدخال رقم صحيح فقط")
هذه الطريقة مفيدة في الحالات البسيطة، لكنها ليست مثالية دائمًا؛ لأن isdigit() لا تتعامل مع علامة السالب في الأرقام السالبة.
مثال:
"-5".isdigit()
سترجع False لأن علامة السالب ليست رقمًا.
{alertWarning} للمبتدئين: isdigit جيدة للأرقام الصحيحة الموجبة فقط غالبًا، أما try except فهي أوسع وأفضل في أغلب البرامج.
ماذا لو كان الرقم عشريًا؟
إذا أدخل المستخدم رقمًا عشريًا مثل:
12.5
فإن هذا الكود يسبب خطأ:
int("12.5")
لأن النص "12.5" لا يمثل عددًا صحيحًا بصيغة مباشرة. إذا كنت تتوقع أرقامًا عشرية، استخدم float() بدل int().
try:
price = float(input("أدخل السعر: "))
print("السعر هو:", price)
except ValueError:
print("الرجاء إدخال رقم صحيح أو عشري")
استخدم int() للأعداد الصحيحة مثل العمر وعدد المنتجات، واستخدم float() للأرقام العشرية مثل السعر والوزن والنسبة.
مثال عملي: برنامج معرفة الزوجي والفردي بطريقة آمنة
في درس معرفة هل الرقم زوجي أم فردي في Python استخدمنا int() لتحويل إدخال المستخدم إلى رقم. الآن سنكتب نسخة آمنة من البرنامج:
try:
number = int(input("أدخل رقمًا: "))
if number % 2 == 0:
print("الرقم زوجي")
else:
print("الرقم فردي")
except ValueError:
print("خطأ: الرجاء إدخال رقم صحيح")
هذه النسخة أفضل لأنها تتعامل مع الإدخال الخاطئ، ولا تجعل البرنامج يتوقف فجأة.
خطأ شائع: تحويل قيمة فارغة إلى int
إذا ضغط المستخدم على Enter بدون كتابة أي شيء، فإن القيمة تكون نصًا فارغًا:
""
وهذا يسبب نفس الخطأ عند استخدام int():
number = int("")
لذلك عند التعامل مع إدخال المستخدم، من الأفضل دائمًا استخدام try except أو التحقق من القيمة قبل تحويلها.
خطأ شائع: كتابة رقم مع كلمات
هذا الكود يسبب الخطأ أيضًا:
int("10 years")
رغم أن النص يحتوي على الرقم 10، إلا أنه يحتوي أيضًا على كلمة years، لذلك لا يستطيع int() تحويله مباشرة.
الصحيح أن تكون القيمة رقمًا فقط:
int("10")
جدول سريع لأسباب الخطأ وحلوله
| القيمة | هل تسبب الخطأ؟ | السبب | الحل |
|---|---|---|---|
"25" |
لا | نص رقمي صحيح | int("25") |
"hello" |
نعم | نص غير رقمي | استخدم try except |
"12.5" |
نعم مع int() |
رقم عشري كنص | استخدم float() |
"" |
نعم | إدخال فارغ | تحقق من الإدخال أو استخدم try except |
"10 years" |
نعم | رقم مع كلمات | اجعل الإدخال رقمًا فقط |
أفضل طريقة لتجنب الخطأ
لتجنب خطأ ValueError: invalid literal for int() with base 10 اتبع هذه النصائح:
- لا تستخدم
int()على نص غير رقمي. - تذكر أن
input()ترجع نصًا دائمًا. - استخدم
try exceptعند التعامل مع إدخال المستخدم. - استخدم
float()إذا كنت تتوقع أرقامًا عشرية. - اكتب رسالة واضحة للمستخدم تخبره بما يجب إدخاله.
- لا تفترض أن المستخدم سيكتب القيمة الصحيحة دائمًا.
أسئلة شائعة عن خطأ ValueError invalid literal for int
هل الخطأ يعني أن int لا تعمل؟
لا. الدالة int() تعمل بشكل طبيعي، لكن القيمة التي أرسلتها لها غير مناسبة. مثلًا int("10") صحيح، لكن int("hello") غير صحيح.
لماذا input ترجع نصًا حتى لو أدخلت رقمًا؟
هذه طبيعة input() في بايثون؛ فهي تقرأ إدخال المستخدم كنص. لذلك نحتاج إلى تحويل النص إلى رقم باستخدام int() أو float() حسب الحاجة.
هل isdigit أفضل من try except؟
ليست دائمًا. isdigit() مناسبة في الحالات البسيطة للأرقام الموجبة فقط، أما try except فهي أفضل غالبًا لأنها تتعامل مع حالات أكثر مثل الأرقام السالبة والأخطاء المختلفة.
متى أستخدم float بدل int؟
استخدم float() عندما تتوقع رقمًا عشريًا مثل السعر أو الوزن أو النسبة. أما int() فاستخدمها مع الأعداد الصحيحة مثل العمر أو عدد العناصر.
روابط مفيدة
- بايثون بالمثال 2: معرفة هل الرقم زوجي أم فردي في Python
- أساسيات بايثون 7: أنواع البيانات في Python
- فن قراءة رسائل الخطأ في بايثون للمبتدئين
- مشكلة وحل 5: حل خطأ IndexError list index out of range في Python
- محرر بايثون العرب لتجربة الأكواد أونلاين
- توثيق Python الرسمي لدالة int
خلاصة الحل
خطأ ValueError: invalid literal for int() with base 10 يظهر عندما تحاول تحويل قيمة غير صالحة إلى عدد صحيح باستخدام int(). أكثر سبب شائع هو أن المستخدم أدخل نصًا أو قيمة فارغة أو رقمًا عشريًا بينما البرنامج يتوقع عددًا صحيحًا.
مثال خاطئ:
int("hello")
والحل الأفضل عند التعامل مع إدخال المستخدم هو استخدام try except:
try:
number = int(input("أدخل رقمًا: "))
print(number)
except ValueError:
print("الرجاء إدخال رقم صحيح فقط")
{alertSuccess} الخلاصة السريعة: إذا كنت تستخدم input مع int، فتوقع دائمًا أن المستخدم قد يدخل قيمة خاطئة، واستخدم try except لحماية البرنامج.
تمرين بسيط لك
اكتب برنامجًا يطلب من المستخدم إدخال عمره، ثم:
- إذا أدخل رقمًا صحيحًا، اطبع العمر.
- إذا أدخل نصًا أو ترك الإدخال فارغًا، اطبع رسالة: الرجاء إدخال عمر صحيح.
- إذا أدخل رقمًا أقل من صفر، اطبع رسالة: العمر لا يمكن أن يكون سالبًا.
حاول استخدام try except مع جملة if داخل البرنامج.