应如何注释 NamedTemporaryFile?

How should a NamedTemporaryFile be annotated?

我按照 中的建议尝试了 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:

表示没有可以表示的super-class,_TemporaryFileWrapper就是“module-private”。它看起来也没有任何成员使其成为现有 Protocol * 的一部分(IterableContextManager 除外;但您没有使用这些方法在这里)。

我认为您需要使用 _TemporaryFileWrapper 并忽略警告:

from tempfile import _TemporaryFileWrapper  # Weak error

def example(tmp: _TemporaryFileWrapper) -> str:
    print(tmp.file)
    return tmp.name

如果你真的想要一个干净的解决方案,你可以 Protocol that includes the attributes you need, and have it also inherit from Iterable and ContextManager。然后你可以 type-hint 使用你的自定义 Protocol.


* 后来有人指出它确实满足 IO,但 OP 需要 IO 中没有的属性,因此无法使用。