Pyjnius: Das Erben von Java-Klassen funktioniert nicht

Erstellt am 22. Aug. 2012  ·  7Kommentare  ·  Quelle: kivy/pyjnius

Ein Teil des Problems ist, dass JavaMetaClass. new geht davon aus, dass es immer aufgerufen wird, um einen Proxy zu erstellen, wenn es für jede untergeordnete Klasse aufgerufen wird. Auf der gleichen Linie muss die Handhabung der jclass_registry auf tatsächliche Proxys beschränkt werden. Etwas anderes, das ich gefunden habe, ist, dass die Behandlung von Objekten, die von Java zurückgegeben werden, lasch ist, was es unmöglich macht, sie an Java-Methoden zurückzugeben.

An einigen dieser Probleme kann ich zu gegebener Zeit arbeiten.

Ich mag es sehr, wie schnell jnius Java lädt und in der Lage ist, die neuesten Versionen von Python zu verwenden.

Möchten Sie dieses Problem unterstützen? Setzen Sie ein Kopfgeld darauf aus! Wir akzeptieren Prämien über Bountysource .

enhancement

Alle 7 Kommentare

Entschuldigen Sie die Verzögerung, können Sie für jedes dieser Probleme eine genauere Beschreibung (Testfälle?) bereitstellen? Ich habe mit einigen Arbeiten begonnen, um die Vererbung von Java-Klassen von Python (unter Verwendung von Proxys) zu ermöglichen, aber es ist nicht vollständig, aber die Probleme, auf die Sie hier hinweisen, scheinen lose damit verbunden zu sein und sollten wahrscheinlich in mehrere verschiedene Probleme aufgeteilt werden.

Tut mir leid, dass ich in die Diskussion komme, aber das Erben einer Java-Klasse ist möglicherweise nicht das, was Sie brauchen @Apalala . Ich denke, es ist eine bessere Idee, die Java-Klasse in eine Python-Klasse einzuschließen, wie es in dieser Klasse der Fall ist. Im verknüpften Code ist dies möglicherweise nicht offensichtlich, da alle Autoklassen in java.py ausgeführt werden, der Code jedoch äquivalent ist

class MyJavaWrapperClass(AnyPythonClassOrMixin):

    def __init__(self, *args, **kwargs):
        JavaClass = autoclass('org.uber.cool.JavaClass`)
        self._my_java_object = JavaClass(*args, **kwargs)  # use double underscore to "hide" the Java object

Die Gründe, die Java-Klasse nicht zu erben, sind:

  • Java-Methoden verwenden Java-Namenskonventionen und sehen in Python-Code hässlich aus, Sie werden höchstwahrscheinlich die Methoden umbenennen wollen, damit sie ein Python-Aussehen haben und andere Entwickler, die an pep8 gewöhnt sind, nicht überraschen (außer wenn Sie altes verdrehtes und altes Zope machen Code...)
  • Im Allgemeinen vermeidet es, das Python-Objekt -Dict mit von Java geerbten Methoden zu überladen, einige Java-Methoden haben nichts mit Python-Bindungen zu tun, sie werden kaum aufgerufen, vielleicht nie. Das Umschließen der Java-Klasse macht die Python-Klasse sauberer in REPL und vermeidet möglicherweise schreckliche Aufrufe von nicht unterstützten Java-Methoden. Beachten Sie die Tatsache, dass Java-Methoden immer noch leicht verfügbar sind, wenn Sie den doppelten Unterstrich nicht verwenden.
  • Zu guter Letzt besteht eine hohe Wahrscheinlichkeit, dass Sie vor oder nach dem Aufruf einiger Java-Methoden Boilerplate-Code hinzufügen müssen. Sie werden höchstwahrscheinlich einige Java-Methoden in Python überschreiben, damit Sie die richtige Typ-/Klassenkonvertierung oder andere Dinge durchführen , sodass Sie am Ende eine Python-Methode für die Java-Methode erstellen, genau wie Sie es tun würden, wenn Sie die Java-Klasse umschließen, anstatt sie zu erben, während Sie immer noch in der Lage sind, A) die Methode umzubenennen, B) das Diktat sauber zu halten. Schauen Sie sich die Methoden von class Element , class Node und class Relationship im Diagramm an, fast alle haben Boilerplate-Code, auch wenn es meistens darum geht, die API pythonischer zu machen;)

Aus Sicht der Leistung glaube ich nicht, dass es Auswirkungen gibt, aber @tshirtman weiß es vielleicht besser.

Eine andere Sache, das Umhüllen von Java-Objekten funktioniert jetzt und wirklich gut :-)

Ist das Überschreiben der Java-Methode mit Python-Code vorerst möglich?
Was ist mit der Java-Klassenvererbung?

Ich habe ziemlich viel Zeit damit verbracht, darin zu suchen, und ich war zu dem Schluss gekommen, dass es keinen praktischen Weg gab, außer Java-Bytecode zur Laufzeit zu generieren, es gibt Bibliotheken, um das zu tun, aber das fühlte sich an wie Hinzufügen eine Menge Komplikationen für die Bibliothek und wahrscheinlich außerhalb des Geltungsbereichs. Ich bin mir nicht sicher, ob ich schließen soll, aber ich glaube nicht, dass daran gearbeitet wird, also wäre es nicht unvernünftig, es als nicht behoben zu markieren.

@monami7001 irgendwelche Fortschritte?

Das war vor ~ 4 Jahren, und meines Wissens nein, das Generieren von Java-Bytecode zur Laufzeit scheint immer noch die einzige Option zu sein (und vielleicht ist es nicht so schlimm wie ich, und wir sollten uns das ansehen).

Eine Problemumgehung ist:

  1. Erstellen Sie ein separates Java-Projekt, einschließlich der android.jar-Datei der angestrebten Android-Versions-API
  2. Code implementieren (Vererbung/Überschreibungen...)
  3. in Glas exportieren
  4. in buildozer importieren

um es mit autoclass zu verwenden

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen