تقنية

put: هل رفع الخطأ يعني أن المصفوفة لم تتغير؟

حالة الاستدعاء والوجهة في ثلاثة مسارات.
قد يبقى تعديل بعد الخطأ.

قد تتغير الوجهة رغم رفع الخطأ في put. [1] نختبر أثر ترتيب فهرسين على القيم الباقية.

سجّل حالة الاستدعاء وحالة الوجهة

تستبدل put عناصر الوجهة عند فهارس تُفسّر على المصفوفة المسطحة. [1] وتنبه وثائقها إلى احتمال تغير الوجهة إذا وقع استثناء في وضع raise. [1] لا نقرأ كلمة raise على أنها وعد بإرجاع البيانات القديمة.

تربط صفحة ndarray.put الطريقة بالدالة المكافئة put. [2] نختبر في ما يلي الدالة np.put تحديدًا؛ لا نضيف عدّ استدعاءات لطريقة لم نشغّلها.

نختار NumPy 2.3.5 ووجهة a=np.array([2,7,-1,4],dtype=np.int64). الشكل (4,)، وعلم الملكية والتجاور بترتيب C صحيحان في كل وجهة مستقلة من تجربتنا.

القيم مؤلفة بلا وحدة. الفهارس الصالحة غير السالبة لهذه الوجهة تبدأ من صفر وتنتهي عند 3. نضع الفهرس 9 عمدًا خارجها، ونحفظ البداية قبل كل محاولة.

نراجع سجلين منفصلين: هل انتهى الاستدعاء بنجاح أو باستثناء؟ وما القيم التي بقيت في الوجهة بعده؟ وجود سجل الحالة لا يغني عن قراءة البيانات إذا كان الأثر السابق مهمًا.

ضع الفهرس الصحيح أولًا

نفذنا np.put(a,[0,9],[100,200],mode="raise") والتقطنا IndexError. بعد المحاولة قرأنا a=[100,7,−1,4]، بالنوع int64 والشكل (4,).

الرقم 100 وصل إلى الموضع 0. أما 200 فلم يصبح عنصرًا في هذه الوجهة: الموضع 9 غير موجود فيها، ولم تمدد العملية طولها لتستوعبه.

في مرجع قوائمنا نمشي على الفهرسين بالترتيب. نكتب 100 عند 0، ثم نتوقف عند 9 لكونه خارج المجال. الناتج المرجعي [100,7,−1,4]، لا البداية الأصلية ولا قائمة أطول.

في فرع NPY_RAISE المقروء من مصدر الإصدار 2.3.5، يفحص المسار الفهرس داخل حلقة النقل ويذهب إلى الفشل عند رفضه. [3] قرأنا هذا الفرع وتنظيف الفشل فقط؛ لم نثبت تطابق المصدر مع الملف الثنائي المثبت.

التقطنا الاستثناء كي نقرأ الوجهة بعده. الالتقاط نفسه لا يعيد 2 إلى الموضع 0 في تجربتنا؛ حفظنا قيمة البداية والمخرجات منفصلتين ولم نبدل إحداهما بالأخرى في التقرير.

بدّل ترتيب الفهارس ثم قارن بالنجاح

أنشأنا وجهة ثانية تبدأ [2,7,−1,4]. مررنا الفهارس [9,0] والقيم [100,200]، مع raise. ارتفع IndexError أيضًا، لكن الوجهة بقيت [2,7,−1,4].

في هذا الترتيب يصادف المرجع الفهرس 9 أولًا، فيتوقف دون كتابة. لا نفترض أن 200 سيصل لاحقًا إلى الموضع 0 بعد رفض أول فهرس؛ التشغيل المحفوظ لم يفعل ذلك.

الحالتان رفعتا نوع الخطأ نفسه وتستعملان أرقام الفهارس نفسها، لكن ترتيبهما اختلف. لذلك لا يكفي ملخص يقول فشل بسبب فهرس خارج المجال لاستنتاج القيم التي بقيت.

للتحكم الناجح أنشأنا وجهة ثالثة من البداية نفسها، ثم استدعينا put بالفهارس [0,1] والقيم [100,200]. رجع None، وصارت الوجهة [100,200,−1,4].

نقرأ None بوصفها رجوع الاستدعاء الناجح، لا قائمة نتائج. حفظنا البيانات من a بعد التشغيل. هكذا نميز النجاح الكامل عن الكتابة الجزئية السابقة لخطأ، وعن الرفض قبل أي كتابة في المثال.

كتابة صحيحة ثم فهرس خارج المجال.
الفشل اللاحق لا يلغي الكتابة السابقة في المثال.

راجع الفحوص وحدود الاستنتاج

أضفنا البداية الصفرية [0,0,0,0] والثابتة [5,5,5,5] والتركيبات الستة عشر من {−2,3} في أربع خانات. مع المثال صار لدينا 19 مجموعة مختلفة.

لكل مجموعة أنشأنا ثلاث وجهات جديدة لمسارات [0,9] و[9,0] و[0,1]. قيم الكتابة هي [100+c,200+c]، حيث c رقم الحالة بدءًا من صفر؛ لا نعيد استخدام وجهة تغيرت في مسار سابق.

نفذنا 57 استدعاء put وأنشأنا 57 مصفوفة مدخل صريحة. سجلنا 38 حالة IndexError و19 رجوعًا ناجحًا بقيمة None، و456 قيمة عددية للوجهات قبل المحاولات وبعدها.

قارنّا الأعداد بمرجع قوائم Python مستقل يكتب عند فهرس صالح ويتوقف عند أول فهرس خاطئ. راجعنا أيضًا نوع كل وجهة وشكلها؛ لا نستخدم مخرجات استدعاء ناجح مرجعًا لاستدعاء فاشل.

لم نفحص الفهارس السالبة أو المكررة أو wrap وclip أو الوجهة الفارغة أو قيم كتابة أقصر أو تخطيطات غير متجاورة أو القراءة فقط أو الفئات المشتقة أو نوع object أو التزامن أو الأداء.

لا نحول هذا المثال إلى ضمان لإلغاء التغييرات أو حفظها في كل مكتبة. عند قراءة تقرير تجربتنا، احفظ بداية الوجهة وترتيب الفهارس وحالة الاستدعاء والقيم النهائية معًا؛ كل سجل يجيب عن جزء مختلف من السؤال.

الفهارسحالة الاستدعاءالوجهة بعده
[0,9]IndexError[100,7,−1,4]
[9,0]IndexError[2,7,−1,4]
[0,1]None / نجاح[100,200,−1,4]

للتوسع: القناع وقيمة البداية.

المراجع

  1. NumPy put
  2. NumPy ndarray put
  3. NumPy versioned put C source

أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.