如何为存根文件中的内部函数或嵌套函数添加类型提示

How to add type hints for an inner or nested function inside the stub file

提问人:Simon Van den Bossche 提问时间:6/17/2022 更新时间:6/17/2022 访问量:386

问:

如何在存根文件中为内部函数(或嵌套函数)添加类型提示?

parsable_base.py中的代码

class TemplateBase:
    def copy(self, _parent=None):
        def walk_properties(template_based):
            for prop_holder in template_based.properties.values():
                if isinstance(prop_holder.prop, TemplateBase):
                    walk_properties(prop_holder.prop)
                elif isinstance(prop_value, PrimitiveBase):
                    value_copies[prop_value] = prop_value.copy()
                else:
                    references.append(prop_value)

        value_copies = {}
        references = []
        walk_properties(self)

parsable_base.pyi 中的代码

class TemplateBase(ParsableBase):
    def copy(self: _T, _parent=...) -> _T: ...

我想在内部函数中为参数添加一个类型提示()。TemplateBasetemplate_basedwalk_properties

我知道我可以将其添加到代码文件(parsable_base.py)中,例如:

        def walk_properties(template_based: TemplateBase) -> None:

但是我想保持我的代码文件干净并将其添加到存根文件(parsable_base.pyi)中。 我认为它会是这样的:

class TemplateBase(ParsableBase):
    def copy(self: _T, _parent=...) -> _T:
        def walk_properties(template_based: TemplateBase) -> None: ...

但是我的 IDE (PyCharm) 无法识别它,所以我认为这是错误的。

我该如何正确地做到这一点。

parsable_base.py 和 parsable_base.pyi 位于同一文件夹(包)中。

蟒蛇 python-3.x

评论

2赞 Anentropic 6/17/2022
如果这是您自己的代码,最好在文件本身中添加注释,而不是单独的存根文件。如果您正在为第三方包制作存根,那么内部函数不是界面的可见部分,因此我怀疑是否可以键入它。

答:

0赞 Tom Aarsen 6/17/2022 #1

我相信这是您面临的问题的最小版本:

class A:
    def func(self, var: A) -> None:
        ...

这会产生:

Traceback (most recent call last):
  File "...\72658624.py", line 2, in <module>
    class A:
  File "...\72658624.py", line 3, in A
    def func(self, var: A) -> None:
NameError: name 'A' is not defined

这个问题可以通过从以下位置导入来解决:annotations__future__

from __future__ import annotations

class A:
    def func(self, var: A) -> None:
        ...

现在它可以正确编译。有关更多信息,请参见 PEP 563。简而言之,这允许对尚未定义的名称进行类型提示。可以猜到,当 Python 解析文件时,遇到 时类尚未完全定义,导致问题。Avar: A

评论

0赞 joanis 6/17/2022
__future__是 Python 2 的东西,这与 Python 3 仍然相关吗?(我知道它仍然有效,这就是重点,但我很确定它不需要。
0赞 Tom Aarsen 6/17/2022
我很确定它仍在使用中。例如,该功能是在 2017 年为 Python 3.7 提供的。就像那时一样,它指的是(潜在的)未来功能。在此示例中,需要它才能编译程序(我在 Python 3.10 中运行)。annotations__future__
1赞 joanis 6/17/2022
好吧,我不知道未来仍然相关,但我想随着新功能的不断添加,它仍然有意义。感谢您的澄清!
1赞 Numerlor 6/17/2022 #2

嵌套函数不是 API 的一部分,因为它是不可访问的(例如,尝试在函数下键入随机变量会执行相同的操作),因此存根文件无法记录它。

如果库是你自己的,我建议你只在 Python 文件中输入