NamedTemporaryFile 应该如何注释?

问题描述 投票:0回答:2

我按照

为文件或类文件对象键入提示?
中的建议尝试了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 运行良好。所以代码没问题。

python python-typing mypy
2个回答
12
投票

我认为这不能轻易地通过类型提示来实现。

如果你检查

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
中没有的属性,所以无法使用。


1
投票

另一种方法是使用:

import typing

def example(tmp: typing.IO[typing.Any]) -> str:
    print(tmp.file)  # type: ignore
    return tmp.name  # type: ignore

诚然,它在强类型方面存在缺陷,但这可能是最好的情况方法?

© www.soinside.com 2019 - 2024. All rights reserved.