【问题标题】:python jedi: how to retrieve methods of instances?python jedi:如何检索实例的方法?
【发布时间】:2016-10-07 18:23:14
【问题描述】:

我为屏幕阅读软件构建了具有一些辅助功能的简单文本编辑器。 我正在使用 Python for .NET (pythonnet) 来显示包含富文本框的表单。 当用户在一段时间后按 Tab 键时,它会弹出一个上下文菜单,其中包含所选元素的补全。 好的,它适用于 Python 对象,但不适用于 .net 实时对象,这个问题没有解决方案。 现在,我想用我正在编辑的模块的所有名称和定义构建一个 TreeView 对象。

所以,例如我输入:

import sys
import os
lst = list()

等等... 如果我使用源代码的 jedi.names,我可以检索 os、sys 和 lst。 对于每个名称,我想检索子定义,例如 sys 和 os 模块的函数,以及 lst 的方法。 我找不到使用绝地的方法:

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().

有什么建议吗? 我尝试使用越来越多的编辑器,但可访问性支持非常非常糟糕......

【问题讨论】:

  • 什么是MySource 对象?
  • 您不会期望看到import sys 的任何自动完成,这是一个完整的声明。但是,如果它是 from sys import,那么您会期望一些自动完成选项。
  • @denfromufa,我认为MySource 只是一个包含第一个代码块中显示的源代码的字符串。
  • 您能更好地描述您的用例吗?我很乐意添加此功能(我是 Jedi 的创建者)。你想列出一个实例的所有属性(包括超类)还是你想要一个实例的所有属性的列表,这些属性只在那个类中定义?

标签: python autocomplete python-jedi


【解决方案1】:

这看起来像一个错误,jedi.evaluate.representation.Instance.__getattr__() 错误地阻止了对 .names_dict 的评估。我在绝地存储库中添加了pull request 来解决这个问题。同时,您可以在jedi/evaluate/representation.py 的副本中将“names_dict”添加到whitelist in Instance.__getattr__(),或者使用下面的代码为当前会话自动修补此方法。

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()

我应该注意我不熟悉jedi,所以我不知道defined_names() 是否应该适用于创建实例的定义。上面的代码不会修复像jedi.names("lst = []")[0].defined_names() 这样的引用,并且没有明显的补丁可以做到这一点。所以可能有一些我不知道的更深层次的事情正在发生。希望开发人员能够帮助解决这个拉取请求。

【讨论】:

    猜你喜欢
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2020-06-17
    相关资源
    最近更新 更多