我从字典中创建了一个类,如下所示:
class MyClass:
def __init__(self, dictionary):
for k, v in dictionary.items():
setattr(self, k, v)
我正在尝试弄清楚如何为这个动态生成的类获取智能感知,大多数IDE都可以读取pyi文件来做这类事情。
不过我不想手工写出一个pyi文件。
是否可以示例化这个类并通过编程将一个pyi文件从它写入磁盘?
mypy有stubgen工具,但我不知道是否可以这样使用它。
我可以从mypy导入stubgen并以某种方式给它提供MyClass(<some dict>)
吗?
1条答案
按热度按时间lskq00tm1#
像stubgen这样的静态分析程序是分析动态填充类的错误工具,因为它们无法看到完整类的源代码来给予类的存根,必须在运行时通过运行源代码来首先填充示例属性来生成存根。
假设您有一个动态填充的类,如您的示例所示,
把这个字典传递给构造函数
你想把这个作为你的输出
生成上述输出的最简单方法是挂钩示例创建和初始化,这样就不会影响类中已经存在的
__new__
或__init__
链接的super
调用,这可以通过元类的__call__
方法来实现:然后,你可以将这个类解析为abstract syntax tree,通过添加、移除或转换节点来修改树,然后对转换后的树进行反解析,下面是使用Python标准库
ast.NodeVisitor
的一个可能的实现:仅限Python 3.9及以上版本
然后,您可以像往常一样运行类,然后检查该高速缓存
_CLASS_TO_STUB_SOURCE_DICT
中存储的内容:在实践中,
.pyi
文件在 per-module 的基础上形成类型接口,因此上面的实现不能立即使用,因为它只适用于一个类。您还必须对.pyi
模块中的其他类型的节点做更多的处理,决定如何处理未注解的节点、重复导入等。在将源代码写入.pyi
文件之前,您可以使用stubgen,它可以分析模块的静态部分,然后您可以获取该输出并编写ast.NodeTransformer
,将该输出转换为动态生成的类。