with - vim python autocomplete



Python Jedi: Wie Methoden der Instanzen abrufen? (1)

Ich habe einen einfachen Texteditor mit einigen Eingabehilfen für Bildschirmlesesoftware erstellt. Ich verwende Python für .NET (pythonnet), um ein Formular anzuzeigen, das eine Rich-Text-Box enthält. Wenn der Benutzer nach einem Zeitraum auf die Registerkarte "Tab" klickt, wird ein Kontextmenü mit den Fertigstellungen für das ausgewählte Element angezeigt. Ok, es funktioniert gut mit Python-Objekten, aber es funktioniert nicht mit .net Live-Objekten, es gibt keine Lösung für dieses Problem. Jetzt möchte ich ein TreeView-Objekt mit allen Namen und Definitionen des Moduls, das ich bearbeite, erstellen.

Also gebe ich zum Beispiel ein:

import sys
import os
lst = list()

etc ... Wenn ich jedi.names meiner Quelle verwende, kann ich os, sys und lst abrufen. Für jeden Namen möchte ich Unterdefinitionen abrufen, z. B. Funktionen für sys- und os-Modul und Methoden für lst. Ich kann keinen Weg finden, dies mit Jedi zu tun:

names = jedi.names(MySource)
names[0].defined_names() # works for sys
names[1].defined_names() # works for os
names[2].defined_names() # doesn't work for lst instance of list().

Irgendwelche Vorschläge? Ich habe versucht, mehr und mehr Editoren zu verwenden, aber die Barrierefreiheit ist sehr, sehr schlecht ...


Das sieht wie ein Fehler aus, wo jedi.evaluate.representation.Instance.__getattr__() fälschlicherweise die Auswertung von .names_dict . Ich habe eine Pull-Anfrage an das Jedi-Repository hinzugefügt, um dies zu beheben. In der Zwischenzeit können Sie entweder 'names_dict' in der Instance.__getattr__() in Ihrer Kopie von jedi/evaluate/representation.py zur Whitelist hinzufügen oder den folgenden Code verwenden, um diese Methode automatisch für die aktuelle Sitzung zu patchen.

import jedi

def patch_jedi():

    __old__getattr__ = jedi.evaluate.representation.Instance.__getattr__

    def __patched__getattr__(self, name):
        if name == 'names_dict':
            # do a simplified version of __old__getattr__, bypassing the name check
            return getattr(self.base, name)
        else:
            # use standard behavior
            return __old__getattr__(self, name)

    # test whether jedi has been updated to avoid the Instance.defined_names() bug
    try:
        jedi.names("lst = list()")[0].defined_names()
    except AttributeError as e:
        if e.args[0].startswith("Instance ") and e.args[0].endswith("Don't touch this (names_dict)!"):
            # patch jedi to avoid this error
            print "patching jedi"
            jedi.evaluate.representation.Instance.__getattr__ = __patched__getattr__
        else:
            # something else strange is going on
            raise

patch_jedi()
print jedi.names("lst = list()")[0].defined_names()
# or: print jedi.Script("lst = list()").goto_definitions()[0].defined_names()

Ich sollte beachten, dass ich mit jedi nicht vertraut jedi , also weiß ich nicht, ob defined_names() für Definitionen, die Instanzen erstellen, funktionieren soll. Der obige Code wird keine Referenzen wie jedi.names("lst = []")[0].defined_names() , und es gibt keinen offensichtlichen Patch, um das zu tun. Es kann also etwas tiefer gehen, von dem ich nichts weiß. Hoffentlich wird der Entwickler helfen, dies als Reaktion auf diese Pull-Anfrage zu korrigieren.





python-jedi