我按照
为文件或类文件对象键入提示?中的建议尝试了
typing.IO
,但它不起作用:
from __future__ import annotations
from tempfile import NamedTemporaryFile
from typing import IO
def example(tmp: IO) -> str:
print(tmp.file)
return tmp.name
print(example(NamedTemporaryFile()))
为此,mypy 告诉我:
test.py:6: error: "IO[Any]" has no attribute "file"; maybe "fileno"?
Python 运行良好。所以代码没问题。
我认为这不能轻易地通过类型提示来实现。
如果你检查
NamedTemporaryFile
的定义,你会发现它是一个以: 结尾的函数
return _TemporaryFileWrapper(file, name, delete)
且
_TemporaryFileWrapper
定义为:
class _TemporaryFileWrapper:
这意味着没有可以指示的超类,并且
_TemporaryFileWrapper
是“模块私有”。它看起来也没有任何成员使其成为现有 Protocol
*
的一部分(Iterable
和 ContextManager
除外;但您在这里没有使用这些方法)。
我认为你需要使用
_TemporaryFileWrapper
并忽略警告:
from tempfile import _TemporaryFileWrapper # Weak error
def example(tmp: _TemporaryFileWrapper) -> str:
print(tmp.file)
return tmp.name
如果您确实想要一个干净的解决方案,您可以实现自己的
Protocol
,其中包含您需要的属性,并让它继承自Iterable
和ContextManager
。然后您可以使用自定义的 Protocol
进行键入提示。
*
后来指出它确实满足IO
,但是OP需要IO
中没有的属性,所以无法使用。
另一种方法是使用:
import typing
def example(tmp: typing.IO[typing.Any]) -> str:
print(tmp.file) # type: ignore
return tmp.name # type: ignore
诚然,它在强类型方面存在缺陷,但这可能是最好的情况方法?