如何命名NamedTemporaryFile?

问题描述

我按照Type hint for a file or file-like object?中的建议尝试了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的一部分的成员(IterableContextManager除外;但是您这里没有使用这些方法)。

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

from tempfile import _TemporaryFileWrapper  # Weak error

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

如果您真的想要一个干净的解决方案,可以implement your own Protocol包含所需的属性,并使其也继承自IterableContextManager。然后,您可以使用自定义Protocol进行提示。