如何在 PyCharm 中正确注释 ContextManager?
How to properly annotate a ContextManager in PyCharm?
如何在 PyCharm 中注释 contextmanager
的 yield 类型,以便它正确猜测 with
子句中使用的值的类型 - 就像它猜测的那样在 with open(...) as f
中创建的 f
是一个文件?
例如,我有一个这样的上下文管理器:
@contextlib.contextmanager
def temp_borders_file(geometry: GEOSGeometry, name='borders.json'):
with TemporaryDirectory() as temp_dir:
borders_file = Path(dir) / name
with borders_file.open('w+') as f:
f.write(geometry.json)
yield borders_file
with temp_borders_file(my_geom) as borders_f:
do_some_code_with(borders_f...)
如何让 PyCharm 知道像这样创建的每个 borders_f
都是 pathlib.Path
(从而为 [=19] 上的 Path
方法启用自动完成=])?当然,我可以在每个 with
语句之后做一个像 # type: Path
这样的注释,但似乎可以通过适当注释 temp_border_file
.
来完成
我尝试将 Path
、typing.Iterator[Path]
和 typing.Generator[Path, None, None]
作为 temp_border_file
的 return 类型,并在 borders_file
在上下文管理器的代码中,但它似乎没有帮助。
我相信您可以使用 typing
中的 ContextManager
,例如:
import contextlib
from typing import ContextManager
from pathlib import Path
@contextlib.contextmanager
def temp_borders_file() -> ContextManager[Path]:
pass
with temp_borders_file() as borders_f:
borders_f # has type Path here
这是当前 PyCharm 期:PY-36444
该问题的解决方法是重写示例代码:
from contextlib import contextmanager
@contextmanager
def generator_function():
yield "some value"
with generator_function() as value:
print(value.upper()) # no PyCharm autocompletion
到
from contextlib import contextmanager
from typing import ContextManager
def wrapper() -> ContextManager[str]:
@contextmanager
def generator_function():
yield "some value"
return generator_function()
with wrapper() as value:
print(value.upper()) # PyCharm autocompletion works
还有一个更简单的解决方法,即使用 ContextManager[str]
注释 return 类型,但有多种原因反对这样做:
- mypy 将正确发出此注释的错误,如 PyCharm 问题中更详细的描述。
- 这不能保证在未来工作,因为 PyCharm 有望解决问题并因此打破此解决方法
如何在 PyCharm 中注释 contextmanager
的 yield 类型,以便它正确猜测 with
子句中使用的值的类型 - 就像它猜测的那样在 with open(...) as f
中创建的 f
是一个文件?
例如,我有一个这样的上下文管理器:
@contextlib.contextmanager
def temp_borders_file(geometry: GEOSGeometry, name='borders.json'):
with TemporaryDirectory() as temp_dir:
borders_file = Path(dir) / name
with borders_file.open('w+') as f:
f.write(geometry.json)
yield borders_file
with temp_borders_file(my_geom) as borders_f:
do_some_code_with(borders_f...)
如何让 PyCharm 知道像这样创建的每个 borders_f
都是 pathlib.Path
(从而为 [=19] 上的 Path
方法启用自动完成=])?当然,我可以在每个 with
语句之后做一个像 # type: Path
这样的注释,但似乎可以通过适当注释 temp_border_file
.
我尝试将 Path
、typing.Iterator[Path]
和 typing.Generator[Path, None, None]
作为 temp_border_file
的 return 类型,并在 borders_file
在上下文管理器的代码中,但它似乎没有帮助。
我相信您可以使用 typing
中的 ContextManager
,例如:
import contextlib
from typing import ContextManager
from pathlib import Path
@contextlib.contextmanager
def temp_borders_file() -> ContextManager[Path]:
pass
with temp_borders_file() as borders_f:
borders_f # has type Path here
这是当前 PyCharm 期:PY-36444
该问题的解决方法是重写示例代码:
from contextlib import contextmanager
@contextmanager
def generator_function():
yield "some value"
with generator_function() as value:
print(value.upper()) # no PyCharm autocompletion
到
from contextlib import contextmanager
from typing import ContextManager
def wrapper() -> ContextManager[str]:
@contextmanager
def generator_function():
yield "some value"
return generator_function()
with wrapper() as value:
print(value.upper()) # PyCharm autocompletion works
还有一个更简单的解决方法,即使用 ContextManager[str]
注释 return 类型,但有多种原因反对这样做:
- mypy 将正确发出此注释的错误,如 PyCharm 问题中更详细的描述。
- 这不能保证在未来工作,因为 PyCharm 有望解决问题并因此打破此解决方法