Python集成开发环境是否可以为动态生成的类属性提供自动完成功能?

16
有没有什么技巧可以让IDE为动态生成的类属性提供代码补全?例如:

class A:
    
    def __init__(self):
        setattr(self, "a", 5)


此代码将把名为aA类属性设置为5的值。但IDE不知道a,因此您不能获得它的代码补全。我已经阅读到可以钩取__dir__方法,但该答案中提出的建议对我没有用。有人有任何想法吗?

2
我对“踩赞”也不太确定。我的直觉告诉我,你的问题的答案可能是“否”,因为静态分析在此处看不到任何东西,但是,JIT是一种存在,也许有一些聪明的IDE魔法可以做到这一点。 - roganjosh
我的想法也是如此,但如果有一个黑客方法可以让它工作起来就太好了。也许有一位Python巫师能帮助我 :) - CiaranWelsh
哪些IDE?还有其他限制吗?(例如,您可以使用类型注释,如a:int吗?文档字符串?) - jonrsharpe
我使用Pycharm,但也很有兴趣让它与其他工具一起使用。是的,类型注释是被允许的...事实上,我对任何想法都感兴趣。我遇到过这个问题几次,想知道是否存在任何策略,无论需要哪些工具(如类型注释)。感谢您的回复。 - CiaranWelsh
3个回答

15

我相信你会在这里找到答案。简而言之,Pycharm目前不支持动态属性(也许在可预见的未来也不会支持)。这是因为它静态地分析代码,无法“看到”一个类可能具有的属性。另一方面,当你在(比如)iPython中运行代码时,一旦创建了这样一个类的实例,编辑器可以获得驻留在内存中的特定实例的属性,从而在自动完成中显示它们。在这种情况下,__dir__很有帮助。我认为其他IDE也应该是如此。

因此,如果你真的需要自动完成功能,你可以尝试使用Jupyter笔记本。但是,你必须在获得自动完成之前实例化你的变量。

另一个可能的解决方案是利用IDE支持.pyi文件(Python接口文件存根)。你可以向你的代码中添加一个小片段,该片段将实例化带有动态属性的类,并编写一个类接口文件(.pyi)。然后IDE将用它进行自动完成。显然,这个解决方案将有一个“一次运行延迟”,但是在PyCharm中,你可以通过点击类名旁边的星号来切换到这样的文件,当有大量更改时,你可以手动更新它。


1
你如何通过编程实现 写下一个类接口?mypy 有 stubgen 工具,但我不认为它可以导入并针对像这样动态创建的类运行。是否有一种方法可以从实例化的类生成 pyi 文件? - red888
init() 函数内部创建一个 .pyi 文件,并将所需内容写入其中。 - igrinis

2
为此,我需要使用联合类型来获取所有可能的自动完成选项。虽然写起来需要额外的时间,但当我的程序变得庞大时,这是值得的。
from typing import Union


class dynamic1(object):
    def __init__(self):
        self.b = 5
        self.c = 0


class dynamic2(dynamic1):
    def __init__(self):
        self.e = 10
        self.d = 11


class dynamic3:
    def __init__(self):
        self.f = 12


def func(li):
    return li[1]


def func() -> Union[dynamic1, dynamic2, dynamic3]:
    a = [dynamic1(), dynamic2(), dynamic3()]
    b = func(a)
    return b

Code in action


0

Spyder提供自动建议选项而不是自动完成。Kite集成可能有助于更快地设置代码。Kite实际上是一个自动完成插件。您也可以在Visual Studio Code中使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接