python - 上下文管理器处理路径上的类型提示
问题描述
代码(在@juanpa.arrivillaga 的帮助下修复:
"""Helpers that can be used for context management."""
import logging
import os
from contextlib import contextmanager
from pathlib import Path
from typing import Union, Iterator, Optional
_LOGGER = logging.getLogger(__name__)
@contextmanager
def working_directory(temporary_path: Union[Path, str], initial_path: Optional[Union[Path, str]] = None) -> Iterator[None]:
"""Changes working directory, and returns to `initial_path` on exit. It's needed for PRAW for example,
because it looks for praw.ini in Path.cwd(), but that file could be kept in a different directory.
`initial_path` can be used for example to change working directory relative to the script path, or
to end up in a different directory than Path.cwd() of the calling script.
Inspiration: https://stackoverflow.com/questions/41742317/how-can-i-change-directory-with-python-pathlib
"""
_LOGGER.debug('Working directory of the calling script: %s', Path.cwd())
_LOGGER.debug('temporary_path = %s', temporary_path)
_LOGGER.debug('initial_path = %s', initial_path)
if not isinstance(temporary_path, (Path, str)):
raise TypeError('"temporary_path" is not of type `Path` or `str`')
if initial_path is None:
initial_path = Path.cwd()
else:
initial_path = Path(initial_path).absolute()
if not initial_path.is_dir():
initial_path = initial_path.parent
try:
os.chdir(initial_path / temporary_path)
_LOGGER.debug('Temporarily changed working directory to: %s', Path.cwd())
yield
finally:
os.chdir(initial_path)
我所做的打字注释是否正确?
另外,有没有更 Pythonic 的方式来编写这个函数?你会改变什么?我也会在 CodeReview 中发布它。
解决方案
打字很好,你的代码中只是有 mypy 揭示的错误。如果两者都是initial_path
,那么这将失败。这就是它抱怨的原因。temporary_path
str
Path
您只能在一个没有(坏习惯,IMO)的分支中转换else
,所以当您到达该行时:
initial_path / temporary_path
可能这两个都是str
。
注意,mypy
不知道这一点,但 if initial_path is not Path.cwd()
不正确。这个陈述永远是假的。除非您指的是对象身份,否则不要将其与事物进行比较is
,在这种情况下,您不需要。
考虑:
>>> from pathlib import Path
>>> Path().cwd() is Path().cwd()
False
做就是了:
def working_directory(
temporary_path: Union[Path, str],
initial_path: Union[Path, str] = Path.cwd()
) -> Iterator[None]:
temporary_path = Path(temporary_path)
initial_path = Path(initial_path)
在您的功能开始时。
推荐阅读
- android - Delphi 10.1 - Google Play Console - 查看和发布错误“此版本不符合 Google Play 64 位要求。”
- r - 如何在 R 中转换这个矩阵?(one-hot,chr)
- r - 在一行代码中创建一个“for循环”
- json - 在 Powershell 中用不同的值查找并替换 JSON 中值的所有实例
- c# - UIElement 不包含“名称”的定义
- angular - 更新 rxjs 中的 observable
- python - 在电子邮件正文中嵌入图像和文本
- javascript - 如果事件值是字符串,你如何使用 R Shiny 将它们发送到 Google Analytics?
- php - 雄辩的访问器和属性命名
- javascript - 如何删除选定的单选按钮并一次标记一个?