🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

كيفية إصلاح خطأ TypeError، كائن NonType غير قابل للاشتراك في لغة Python

⏱️3 min read  ·  484 words

الخطأTypeError: كائن ‘NoneType’ غير قابل للكتابة في Python يعني أنك حاولت فهرسة أو تقطيع شيء ماNone – مثلresult[0] متىresult is None. إنه أحد أخطاء بايثون الأكثر شيوعًا. هنا كل الأسباب والإصلاح.

ماذا يعني “قابل للاشتراك”

الاشتراك هو الوصول إلى عنصر بين قوسين مربعين:x[0], x['key'], x[1:3]. القوائم والإملاءات والسلاسل والصفوف قابلة للاشتراك. None ليس — هكذاNone[0] يثير هذا الخطأ. السؤال الحقيقي هو دائما:لماذا المتغير الخاص بك لا شيء؟

السبب الأول: لا تُرجع الدالة أي شيء ضمنيًا

# 🐛 Function has no return statement (or a path that doesn't return)
def find_user(users, name):
    for user in users:
        if user['name'] == name:
            return user
    # No return when not found → returns None implicitly

result = find_user(users, "Alice")
print(result['email'])   # ❌ TypeError if Alice not found (result is None)

# ✅ Check for None before subscripting
result = find_user(users, "Alice")
if result is not None:
    print(result['email'])
else:
    print("User not found")

السبب 2: الأسلوب الذي يعدل في المكان لا يُرجع أي شيء

# 🐛 list.sort() sorts in place and returns None
numbers = [3, 1, 2]
sorted_nums = numbers.sort()   # ❌ sort() returns None
print(sorted_nums[0])          # TypeError — sorted_nums is None

# ✅ Use sorted() which returns a new list
sorted_nums = sorted(numbers)  # returns a new sorted list
print(sorted_nums[0])          # works

# Same trap with: list.append(), list.reverse(), dict.update()
# These modify in place and return None

السبب 3: dict.get() إرجاع لا شيء

# 🐛 .get() returns None for missing keys
config = {"host": "localhost"}
port = config.get("port")   # None — 'port' not in dict
print(port[0])              # ❌ TypeError

# ✅ Provide a default with .get()
port = config.get("port", 8080)   # default if missing

# ✅ Or check before use
port = config.get("port")
if port is not None:
    use(port)

السبب 4: تطابق Regex لا يُرجع أي شيء

import re

# 🐛 re.match/search return None when no match
match = re.search(r'\d+', "no numbers here")
number = match.group()   # ❌ TypeError — match is None

# ✅ Check the match first
match = re.search(r'\d+', text)
if match:
    number = match.group()
else:
    number = None

السبب 5: إرجاع استعلام API/قاعدة البيانات لا شيء

# 🐛 Database query returns None when no row found
user = db.query("SELECT * FROM users WHERE id = ?", user_id)
name = user['name']   # ❌ TypeError if no user found

# ✅ Always handle the "not found" case
user = db.query("SELECT * FROM users WHERE id = ?", user_id)
if user is None:
    raise NotFoundError(f"User {user_id} not found")
name = user['name']   # safe now

التصحيح: ابحث عن سبب عدم وجوده

# Add a check to see exactly what's None and where
result = some_function()
print(f"DEBUG: result = {result!r}, type = {type(result)}")
# If it prints "result = None", trace back to some_function()
# to find the code path that returns None

# Use a debugger to inspect
import pdb; pdb.set_trace()   # step through and check the value

الأنماط الآمنة لمنع هذا

# Pattern 1: Walrus operator for check-and-use (Python 3.8+)
if (user := find_user(users, name)) is not None:
    print(user['email'])

# Pattern 2: Provide defaults
data = fetch_data() or {}   # empty dict if fetch returns None
value = data.get('key', 'default')

# Pattern 3: Optional chaining alternative (Python has no ?. operator)
name = user['name'] if user else None

# Pattern 4: Return consistent types from functions
def find_user(users, name):
    for user in users:
        if user['name'] == name:
            return user
    return {}   # return empty dict instead of None (if that makes sense)

الأسئلة المتداولة

س: لماذا لا تُرجع وظيفتي “لا شيء” عندما لم أكتب “إرجاع لا شيء”؟
ج: لا تُرجع وظائف بايثون أي شيء ضمنيًا إذا وصلت إلى النهاية بدون عبارة إرجاع، أو إذا وصلت إلى مسار تعليمات برمجية لا يُرجع. سبب شائع: العودة داخل حلقة/إذا لم يتم الوصول إلى ذلك لجميع المدخلات.

س: لماذا لا يعطيsorted_list = my_list.sort() لا شيء؟
A: .sort() فرز القائمة في مكانها وإرجاع لا شيء. استخدمsorted(my_list) والتي تقوم بإرجاع قائمة مرتبة جديدة. ينطبق هذا الفخ على العديد من الأساليب الموضعية (إلحاق، عكس، تحديث).

س: كيف يمكنني الوصول بأمان إلى مفاتيح الإملاء المتداخلة التي قد تكون مفقودة؟
ج: سلسلة.get() مع الإعدادات الافتراضية:data.get('user', {}).get('name', 'unknown'). يقوم كل ‎.get()‎ بإرجاع إملاء فارغ إذا كان مفقودًا، حتى لا تصل السلسلة إلى “لا شيء”.

س: ما الفرق بين هذا و”NoneType ليس له سمة”؟
ج: “غير قابل للاشتراك” منNone[x] (بين قوسين مربعين). “ليس له سمة” منNone.attr (نقطة الوصول). كلاهما يعني أن لديك لا شيء حيث كنت تتوقع كائنًا حقيقيًا – الإصلاح (التحقق من عدم وجود شيء) هو نفسه.

س: هل يجب أن أستخدم المحاولة/الاستثناء أو عمليات التحقق من الحالة؟
ج: تفضل الصريحif x is not None يتحقق من الوضوح عندما لا يكون هناك احتمال متوقع. استخدم المحاولة/باستثناء الحالات الاستثنائية حقًا. يعد التحقق أكثر وضوحًا وأسرع بالنسبة للسيناريو الشائع “قد لا يكون هناك شيء”.

الخلاصة

“كائن ‘NoneType’ غير قابل للاشتراك” يعني أنك تقوم بفهرسة شيء ماNone. الإصلاح الحقيقي ليس بالخط السفلي — بل بالفهملماذا المتغير الخاص بك هو لا شيء: دالة تُرجع لا شيء ضمنيًا، وهي طريقة موضعية مثل.sort() الذي يُرجع لا شيء، أو مفتاح الإملاء المفقود، أو تطابق التعابير المنطقية الفاشلة، أو نتيجة استعلام فارغة. أضفprint(f"{result!r}") لتأكيد ما هو لا شيء، وتتبع مصدره، والحماية باستخدامif x is not None قبل الاشتراك. إن إرجاع الأنواع المتسقة من وظائفك يمنع معظم هذه الأخطاء تمامًا.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা