gpt4 book ai didi

python - 我的: "Item of Union has no attribute"错误

转载 作者:太空宇宙 更新时间:2023-11-04 09:40:51 25 4
gpt4 key购买 nike

尝试学习在 Python 中输入提示。鉴于这两个功能:

from typing import Union, TextIO


def myfunc_ok(file: TextIO):
mydump = file.read()
print(mydump)


def myfunc_error(file: Union[str, TextIO]):
mydump = file.read()
print(mydump)

第一个对 mypy 没问题,但它提示第二个有错误

Item "str" of "Union[str, TextIO]" has no attribute "read"

在这种情况下,我是否错误地使用了类型提示?(使用 python3.7 和 mypy 0.610,也用 py3.6 测试)

最佳答案

您的签名

def myfunc_error(file: Union[str, TextIO]):
...

表示 file 参数可以是 strTextIO,之后在函数体中您尝试访问 .read file 对象的属性,但是如果 filestr,则没有这样的属性,因此会出现错误。

这里至少有 3 种可能性:

  • 不支持 file 类型为 str 的大小写并将 Union[str, TextIO] 替换为 TextIO
  • 使用 isinstance built-in 添加显式类型检查在函数体中

    import io
    ...
    def myfunc_error(file: Union[str, TextIO]):
    if isinstance(file, io.TextIOWrapper):
    mydump = file.read()
    else:
    # assuming ``file`` is a required object already
    mydump = file
    print(mydump)

    从长远来看,这可能会变得难以维护

  • 为给定任务编写 2 个不同的函数:一个用于 str 参数,一个用于 TextIO 参数,例如

    def myfunc_error_str_version(file: str):
    mydump = file
    print(mydump)

    def myfunc_error_text_io_version(file: TextIO):
    mydump = file.read()
    print(mydump)

    这可能会导致很多命名问题(但这取决于用例)

可以使用 functools.singledispatch decorator 改进最后一种方法: 简而言之,这将允许我们定义一个 generic function & 使用名称 myfunc_error 并根据第一个位置参数的类型调用重载(在我们的例子中为 file):

import io
from functools import singledispatch
from typing import TextIO


@singledispatch
def myfunc_error(file: str):
mydump = file
print(mydump)

# using ``typing.TextIO`` will not work because it's just an interface for type annotations,
# "real" types are located at ``io`` module
@myfunc_error.register(io.TextIOWrapper)
def _(file: TextIO):
mydump = file.read()
print(mydump)

注意:除了myfunc_error,我们可以使用我们想要的任何名称来代替_,对于后者mypy将引发名称冲突错误。

关于python - 我的: "Item of Union has no attribute"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51782177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com