为 os.DirEntry 添加类型提示
Add type hint for os.DirEntry
我正在努力向接受 os.DirEntry
对象的函数添加类型提示(这些由 os.scandir()
生成)。这是一个接受 DirEntry
个对象的简单访问器 class:
class FileSystemVisitor:
def visit_dir(self, entry) -> None:
...
def visit_file(self, entry) -> None:
...
FileSystemVisitor
的一个实例被提供给遍历给定目录的子树的 visit()
函数:
def traverse(path: Union[str, pathlib.Path], visitor: FileSystemVisitor) -> None:
for entry in os.scandir(str(path)):
if entry.is_dir(follow_symlinks=False):
visitor.visit_dir(entry)
traverse(entry.path, visitor)
else:
visitor.visit_file(entry)
如何为 FileSystemVisitor.visit_{dir(),file()}
函数中的 entry
参数添加类型提示?为此,我无法导入 DirEntry
。
$ python3.5 -c "from os import DirEntry"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: cannot import name 'DirEntry'
我能想到的一件事是编写一个模仿 DirEntry
的虚拟 class 并将其用于类型提示:
class DirEntryType:
name = None # type: str
path = None # type: str
def inode(self) -> int:
...
def is_dir(self) -> bool:
...
def is_file(self) -> bool:
...
def is_symlink(self) -> bool:
...
def stat(self) -> os.stat_result:
...
但是,添加整个 class 只是为了类型提示那么聪明吗?
如果这很重要,我坚持使用 python3.5
,因此 python3.6
的功能不可用。
编辑
正如avigil在评论中指出的那样,DirEntry
可以在python3.6
中导入:
$ python3.6 -c "from os import DirEntry; print(DirEntry)"
<class 'posix.DirEntry'>
因此,向后兼容的解决方案可以是例如:
# typing_utils.py
class DirEntryStub:
name = None # type: str
path = None # type: str
def inode(self) -> int:
raise NotImplementedError('This class is used for type hints only')
def is_dir(self, follow_symlinks: bool = False) -> bool:
raise NotImplementedError('This class is used for type hints only')
def is_file(self, follow_symlinks: bool = False) -> bool:
raise NotImplementedError('This class is used for type hints only')
def is_symlink(self) -> bool:
raise NotImplementedError('This class is used for type hints only')
def stat(self) -> os.stat_result:
raise NotImplementedError('This class is used for type hints only')
现在我可以输入 FileSystemVisitor
:
try:
from os import DirEntry
except ImportError:
from typing_utils import DirEntryStub as DirEntry
class FileSystemVisitor:
def visit_dir(self, entry: DirEntry) -> None:
...
def visit_file(self, entry: DirEntry) -> None:
...
DirEntry
在 posix 模块中用 C 语言实现,但不幸的是,直到 3.6 版本才在 python 中公开。有关 python 错误跟踪器问题,请参阅 bpo-27038。
对于较早的版本,您可以按照您的建议进行操作并将其存根,除非您足够关心编译您自己的 patched version. This actually wouldn't be too hard since the scandir
implementation comes originally from the scandir 程序包,该程序包可以被修补并作为依赖项引入标准库实现。
我正在努力向接受 os.DirEntry
对象的函数添加类型提示(这些由 os.scandir()
生成)。这是一个接受 DirEntry
个对象的简单访问器 class:
class FileSystemVisitor:
def visit_dir(self, entry) -> None:
...
def visit_file(self, entry) -> None:
...
FileSystemVisitor
的一个实例被提供给遍历给定目录的子树的 visit()
函数:
def traverse(path: Union[str, pathlib.Path], visitor: FileSystemVisitor) -> None:
for entry in os.scandir(str(path)):
if entry.is_dir(follow_symlinks=False):
visitor.visit_dir(entry)
traverse(entry.path, visitor)
else:
visitor.visit_file(entry)
如何为 FileSystemVisitor.visit_{dir(),file()}
函数中的 entry
参数添加类型提示?为此,我无法导入 DirEntry
。
$ python3.5 -c "from os import DirEntry"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: cannot import name 'DirEntry'
我能想到的一件事是编写一个模仿 DirEntry
的虚拟 class 并将其用于类型提示:
class DirEntryType:
name = None # type: str
path = None # type: str
def inode(self) -> int:
...
def is_dir(self) -> bool:
...
def is_file(self) -> bool:
...
def is_symlink(self) -> bool:
...
def stat(self) -> os.stat_result:
...
但是,添加整个 class 只是为了类型提示那么聪明吗?
如果这很重要,我坚持使用 python3.5
,因此 python3.6
的功能不可用。
编辑
正如avigil在评论中指出的那样,DirEntry
可以在python3.6
中导入:
$ python3.6 -c "from os import DirEntry; print(DirEntry)"
<class 'posix.DirEntry'>
因此,向后兼容的解决方案可以是例如:
# typing_utils.py
class DirEntryStub:
name = None # type: str
path = None # type: str
def inode(self) -> int:
raise NotImplementedError('This class is used for type hints only')
def is_dir(self, follow_symlinks: bool = False) -> bool:
raise NotImplementedError('This class is used for type hints only')
def is_file(self, follow_symlinks: bool = False) -> bool:
raise NotImplementedError('This class is used for type hints only')
def is_symlink(self) -> bool:
raise NotImplementedError('This class is used for type hints only')
def stat(self) -> os.stat_result:
raise NotImplementedError('This class is used for type hints only')
现在我可以输入 FileSystemVisitor
:
try:
from os import DirEntry
except ImportError:
from typing_utils import DirEntryStub as DirEntry
class FileSystemVisitor:
def visit_dir(self, entry: DirEntry) -> None:
...
def visit_file(self, entry: DirEntry) -> None:
...
DirEntry
在 posix 模块中用 C 语言实现,但不幸的是,直到 3.6 版本才在 python 中公开。有关 python 错误跟踪器问题,请参阅 bpo-27038。
对于较早的版本,您可以按照您的建议进行操作并将其存根,除非您足够关心编译您自己的 patched version. This actually wouldn't be too hard since the scandir
implementation comes originally from the scandir 程序包,该程序包可以被修补并作为依赖项引入标准库实现。