Pyjnius: فشل العثور على المُنشئ عند وجود مُنشئين متعددين (محملين بشكل زائد)

تم إنشاؤها على ٢٢ أكتوبر ٢٠٢٠  ·  8تعليقات  ·  مصدر: kivy/pyjnius

تم العثور على خطأ في pyjnius عند التعامل مع فئة Java ذات منشئات متعددة.

عندما قمت بتنفيذ كود Java أدناه ، فإن الطريقة الرئيسية ستستدعي المنشئ الثاني وتنتهي برشاقة.
عندما أقوم بتنفيذ كود python أدناه ، فسوف يبلغ عن عدم العثور على المُنشئ.
(jnius.JavaException: No constructor matching your arguments, available: ['(ILjava/lang/String;)V', '(ILjava/lang/String;Ljava/lang/Object;[I)V'])
ولكن عندما أزلت المُنشئ الأول في كود جافا ، فإن كود الثعبان الخاص بي مع pyjnius يمكن أن يجد بشكل صحيح المُنشئ الوحيد وينتهي بأمان.

فئة جافا

public class SampleJavaClass {
    public SampleJavaClass( int arg1, String arg2, int arg3, Object arg4, int... arg5 ) {
    System.out.println("arg1: " + Integer.toString(arg1));
        System.out.println("arg2: " + arg2);
        System.out.println("arg3: " + arg3);
        System.out.println("arg3: " + arg4);
        System.out.println("arg4: " + arg5.toString());
    }

    // the constructor plans to use
    public SampleJavaClass (int arg1, String arg2, Object arg3, int... arg4) {
        System.out.println("arg1: " + Integer.toString(arg1));
        System.out.println("arg2: " + arg2);
        System.out.println("arg3: " + arg3);
        System.out.println("arg4: " + arg4.toString());
    }

    public static void main(String[] args) {
        SampleJavaClass test = new SampleJavaClass(1, "var2", null, 4);
    }
}

كود بايثون مع Pyjnius

import os
currentPath = os.getcwd()
classpath = currentPath + "/SampleJavaClass.class"
import jnius_config
jnius_config.set_classpath('.', classpath)
from jnius import autoclass

def main():
    SampleJavaClass = autoclass("SampleJavaClass")
    SampleJavaClass(1, "var2", None, 4)
    print("Execution finished!")


if __name__ == "__main__":
    main()

التعليق الأكثر فائدة

عندما يستدعي pyjnius أسلوبًا أو مُنشئًا ، فإنه يتحقق أولاً من وجود 0 أو 1 أو عدة مُنشِئات أو عمليات بالاسم المحدد. إذا كان هناك واحد فقط ، فإنه يقوم دائمًا بإجراء المكالمة ، على أمل الأفضل. إذا كان هناك العديد ، فإنه يقوم بعملية التسجيل هذه لمحاولة تحديد ما إذا كان كل منها مقبولًا أم لا. آمل أن يكون واحدًا واحدًا فقط مقبولًا ؛ إذا لم يكن كذلك ، فإنه يرمي خطأ.

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

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

ال 8 كومينتر

هل حاولت استخدام تلميح توقيع المنشئ؟

راجع https://github.com/kivy/pyjnius/blob/307659b13c1e5583fcb25603b7d3732265ffd4a0/tests/test_constructor.py#L54 للحصول على مثال.

عندما يستدعي pyjnius أسلوبًا أو مُنشئًا ، فإنه يتحقق أولاً من وجود 0 أو 1 أو عدة مُنشِئات أو عمليات بالاسم المحدد. إذا كان هناك واحد فقط ، فإنه يقوم دائمًا بإجراء المكالمة ، على أمل الأفضل. إذا كان هناك العديد ، فإنه يقوم بعملية التسجيل هذه لمحاولة تحديد ما إذا كان كل منها مقبولًا أم لا. آمل أن يكون واحدًا واحدًا فقط مقبولًا ؛ إذا لم يكن كذلك ، فإنه يرمي خطأ.

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

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

هل حاولت استخدام تلميح توقيع المنشئ؟

ارى

https://github.com/kivy/pyjnius/blob/307659b13c1e5583fcb25603b7d3732265ffd4a0/tests/test_constructor.py#L54

على سبيل المثال.

حاولت إضافة توقيع كما هو موضح في الكود أدناه للتو ، لكنه أرسل خطأ تأكيد. أين أخطأت؟

خطأ

  File "jnius/jnius_export_class.pxi", line 270, in jnius.JavaClass.__init__
  File "jnius/jnius_export_class.pxi", line 319, in jnius.JavaClass.call_constructor
AssertionError

كود بايثون مع Pyjnius

import os
currentPath = os.getcwd()
classpath = currentPath + "/SampleJavaClass.class"
import jnius_config
jnius_config.set_classpath('.', classpath)
from jnius import autoclass

def main():
    SampleJavaClass = autoclass("SampleJavaClass")
    SampleJavaClass(1, "var2", None, 4, signature="(ILjava/lang/String;Ljava/lang/Object;[I)V")
    print("Execution finished!")


if __name__ == "__main__":
    main()

ها هو الكود ذو الصلة:

            requestedDefn = kwargs.pop('signature', None)
            for definition, is_varargs in definitions:
                found_definitions.append(definition)
                d_ret, d_args = parse_definition(definition)
                if requestedDefn == definition:
                    assert not is_varargs
                    scores=[]
                    score=1
                    scores.append((score, definition, d_ret, d_args, args))
                    break

لماذا لا يمكن استخدام تلميحات التوقيع مع الوسائط المتغيرة؟

لا تهتم ، لقد اكتشفت ذلك ولدي حل لذلك. سأضيفه إلى العلاقات العامة.

enjoybeta لقد أصلحت هذا في العلاقات العامة ، لكن خلاصة القول ، لا يعمل حل تلميح التوقيع في الإصدار الحالي.

cmacdonald ، هل هناك حل آخر يمكنهم استخدامه هنا؟

لا شيء في الجزء العلوي من رأسي - أضف فئة مصنع Java سريعة تستدعي مُنشئ varargs؟

على أي حال ، أقترح أنه يمكننا إغلاق المشكلة لأن إصدار Jnius التالي سيعمل على إصلاح الخطأ.

فكره جيده! يمكن لطريقة المصنع الاعتناء بها إذا كان تغيير كود المصدر خيارًا. إذا لم يكن الأمر كذلك ، فيمكنهم إنشاء فئة مساعدة مساعدة منفصلة تقوم بذلك نيابة عنهم.

متفق عليه ، يمكننا إغلاق هذه المسألة الآن.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

tshirtman picture tshirtman  ·  23تعليقات

Thrameos picture Thrameos  ·  27تعليقات

stania picture stania  ·  6تعليقات

hanslovsky picture hanslovsky  ·  3تعليقات

cthoyt picture cthoyt  ·  11تعليقات