Python аннотации типа из частного импорта (из проклятий) - PullRequest
0 голосов
/ 08 марта 2020

Я только начал использовать аннотации типов и столкнулся с проблемой использования модуля curses в Python. Более конкретно, curses.wrapper(func) ожидает в качестве аргумента функцию, func, принимая в качестве аргумента главное окно, также называемое "stdscr". Однако я не уверен, как аннотировать такую ​​функцию. Например,

from curses import wrapper

def interactive_shell_curses(stdscr: _curses.window) -> None:

выдает ошибку "Имя '_curses' не определено", даже если print(type(stdscr)) печатает <class '_curses.window'>. _curses.window находится в файле _curses.pyi из типизированного. Тем не менее, я не уверен, как импортировать его или даже должен ли я. Кроме того, я не уверен, что наилучшей практикой здесь будет просто воздерживаться от аннотирования interactive_shell_curses.

Пожалуйста, посоветуйте, как разобраться с этим делом!

1 Ответ

2 голосов
/ 08 марта 2020

Модуль Python curses является только оболочкой для библиотеки curses. В частности, это означает, что вы не получите доступ к объекту окна для целей набора (_curses.window становится доступным только после вызова initscr(), и даже если бы это было так, это было бы довольно бесполезно, поскольку библиотека не предоставить подсказки типа).

С другой стороны, вы не можете просто импортировать подсказку типа _CursesWindow из typeshed _curses.pyi, поскольку она не определена во время выполнения. Здесь может помочь константа TYPE_CHECKING. Если TYPE_CHECKING равно True, вы находитесь в режиме проверки типа и импортируете подсказку типа из заглушки. В противном случае вы запускаете код с интерпретатором, который не заботится о подсказках типа, поэтому, например, используйте тип 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)
...