علوم وفضاء

copyto: هل يعفي قناع False من قاعدة التحويل؟

مصدر ووجهة وقناع مستبعد.
مدخل مؤلف ومخرجات مسجلة.

اختيار مواضع النسخ مرتبط بقاعدة التحويل أيضًا. [1]

القناع وقاعدة النوع

copyto تختار النسخ عند True؛ خرق قاعدة التحويل يرفع TypeError، والافتراضي same_kind. [1]

نضع سؤالين: هل يختار القناع كتابة أي موضع؟ وهل يقبل الاستدعاء تحويل نوع المصدر إلى نوع الوجهة؟ نجرب قناعًا يستبعد كل المواضع كي لا نخلط السؤالين.

الأعداد أمثلة مؤلفة بلا وحدة؛ لا نقيس جودة بيانات أو ننفذ سياسة ملء. المقارنة بين تشغيلين مستقلين، فلا نجعل إخفاق الأول نتيجة ناجحة للثاني.

رفض رغم الاستبعاد

أنشأنا src=np.array([2.75,-1.25,4.5],dtype=np.float64)، وdst=np.array([10,20,30],dtype=np.int16). الشكل (3,) لكليهما، في NumPy 2.3.5 على CPython 3.12.14.

بدأنا بالقناع m=[False,False,False] من bool، وشغّلنا np.copyto(dst,src,where=m) داخل try. التقطنا TypeError؛ لم نعامل بقاء [10,20,30] بوصفه دليل نجاح. قارنا بايتات الوجهة قبل المحاولة وبعدها فكانت متطابقة.

كررنا الاستدعاء الافتراضي بوجهة جديدة والقناع [True,False,True]؛ رفع TypeError أيضًا، وبقيت [10,20,30]. ثبات النوعين والسياق يجعل اختلاف القناع هو المقارنة المقصودة.

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

نسخ مسموح محدد

اخترنا casting="unsafe" صراحة. يتيح التوثيق عند هذه السياسة التحويلات دون قيد النوع السابق. [1]

على وجهة تبدأ [10,20,30]، شغّلنا np.copyto(dst,src,where=m,casting="unsafe") بالقناع كله False. أعاد None، وبقيت الوجهة [10,20,30] من int16 وشكل (3,).

ثم شغّلنا العملية نفسها على وجهة جديدة مع القناع [True,False,True]. أعاد None، وصارت الوجهة [2,20,4] من int16 وشكل (3,). الموضع الأوسط يحمل 20 من البداية؛ ليس تحويلًا للعدد −1.25.

العددان 2 و4 لا يساويان 2.75 و4.5. السماح بالعملية لا يثبت حفظ الجزء الكسري؛ نراجع القيم المخزنة إلى جانب قبول نوع التحويل.

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

وجهة قبل النسخ وبعده.
مسارات مسجلة بأنواعها.

مرجع وحدود

يسمي توثيق Python حذف الجزء الكسري اتجاهًا نحو الصفر في math.trunc. [2]

لم نستدع math.trunc في مرجعنا. اخترنا بسطًا صحيحًا n ومقامًا 4؛ نحسب n//4 إذا كان غير سالب، وإلا −((-n)//4). نستعمل القسمة الصحيحة على مقدار موجب ثم نعيد الإشارة؛ مثلًا −5/4 يعطي −1، لا −2.

عددنا كل أزواج البسطين من −15 إلى 15: لدينا 31×31=961 زوجًا. قسمنا على 4 فصارت المصادر من −3.75 إلى 3.75، وأنشأنا float64 بالشكل (2,)، وقارنّا كل زوج بالأقنعة الأربعة الممكنة من طول 2. الإجمالي 961×4=3844 حالة.

في كل حالة تبدأ الوجهة int16 بالقيمتين [10,20]. الفحص الأول يثبت TypeError الافتراضي؛ والثاني ثبات بايتات الوجهة بعده؛ والثالث ناتج unsafe ونوعه وشكله وNone وفق اختيار Python المرجعي.

الفحص الرابع تحكم بمصدر جديد من int16 يحمل الأعداد المرجعية نفسها؛ استدعاء copyto الافتراضي نجح وأعطى الاختيار نفسه ونوعه وشكله وNone. الخامس يثبت بايتات مصدر float64 والقناع. لا نجعل التحكم تغييرًا خفيًا لنوع المصدر الأصلي.

للمثال ذي الثلاثة عناصر، لكل قناع ثلاثة فحوص: الاستثناء وثبات الوجهة؛ ثم ناتج unsafe ونوعه وشكله وNone؛ ثم ثبات المصدر والقناع. صار العدد 3844×5+2×3=19226، ومرت جميع الفحوص.

استبعدنا البث والأشكال غير المتوافقة والمتغيرات المفردة، وNaN واللانهاية وتجاوز المجال والأنواع والسياسات الأخرى، والمصفوفات المتشاركة أو للقراءة فقط. لم نفحص الأداء أو نثبت سلامة الوجهة عند كل فشل محتمل.

احفظ مع النتيجة نوع المصدر والوجهة والقناع والسياسة وحالة الاستدعاء. لا تحول الأرقام القديمة بعد استثناء إلى قيم جديدة ادعيت نسخها، ولا تجعل نجاح unsafe وعدًا بالحفاظ على كل قيمة.

السياسة والقناعحالة الاستدعاءالوجهة بعده
same_kind / FFFTypeError[10,20,30]
same_kind / TFTTypeError[10,20,30]
unsafe / FFFNone[10,20,30]
unsafe / TFTNone[2,20,4]

للتوسع: القناع والتهيئة.

المراجع

  1. NumPy 2.3 — copyto
  2. Python 3.12 — math.trunc

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