来自私有导入的Python类型注释(来自curses)

nij*_*kim 4 python curses types mypy

curses我刚刚开始使用类型注释,并在 Python 中使用模块时遇到了问题。更具体地说,curses.wrapper(func)期望函数 作为参数,func以主窗口(也称为“stdscr”)作为参数。但是,我不确定如何注释这样的函数。例如

from curses import wrapper

def interactive_shell_curses(stdscr: _curses.window) -> None:
Run Code Online (Sandbox Code Playgroud)

print(type(stdscr))即使prints ,也会产生错误“名称'_curses'未定义” <class '_curses.window'>。在typeshed_curses.window文件中找到。_curses.pyi但是,我不确定如何导入它或者我是否应该导入它。另外,我不确定这里的最佳实践是否实际上是避免注释interactive_shell_curses

请高手指教如何处理这种情况!

hoe*_*ing 6

Pythoncurses模块只是库的包装器curses。特别是,这意味着您将无法出于键入目的访问 window 对象(_curses.window仅在调用 后才可用initscr(),即使可以,也毫无用处,因为库本身不提供类型提示)。

另一方面,您不能只_CursesWindowtypesheds导入类型提示_curses.pyi,因为它不是在运行时定义的。这就是TYPE_CHECKING常数可以提供帮助的地方。如果TYPE_CHECKINGTrue,则您处于类型检查模式并从存根导入类型提示。否则,您将使用不关心类型提示的解释器运行代码,因此例如使用类型Any。例子:

import curses
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from _curses import _CursesWindow
    Window = _CursesWindow
else:
    from typing import Any
    Window = Any


def main(stdscr: Window) -> None:
    height, width = stdscr.getmaxyx()
    text = 'Hello world'
    stdscr.addstr(int(height / 2), int((width - len(text)) / 2), text)

    key = 0
    while (key != ord('q')):
        stdscr.refresh()
        key = stdscr.getch()
    return None


if __name__ == '__main__':
    curses.wrapper(main)
Run Code Online (Sandbox Code Playgroud)