gpt4 book ai didi

python - 当内部函数返回可能是 'Union' 的 'None' 时,如何避免类型错误?

转载 作者:行者123 更新时间:2023-12-03 23:02:15 25 4
gpt4 key购买 nike

我在 python 中遇到了联合(和 Optionals,当然)有点奇怪 - 即似乎静态类型检查器针对联合的所有成员测试属性,而不是联合的成员(即似乎过分严格?)。例如,请考虑以下情况:

import pandas as pd

def test_dummy() -> pd.DataFrame:
df = pd.DataFrame()
df = df.fillna(df)
return df
这将创建一个类型警告,如 pd.fillna(..., inplace: Bool = False, ...) -> Optional[pd.DataFrame] (如果 None 则返回 inplace=True )。我怀疑理论上静态类型检查器应该根据参数实现函数的返回变化(因为在编写代码时应该知道),但这有点过分了。
我有以下问题:
  • 解决此问题的最佳方法是什么?我可以想到两种解决方案:
    i) 什么都不做——这会在我的代码中产生丑陋的波浪线
    ii) castfillna 返回到 pd.DataFrame ;我的理解是这是静态类型检查器的信息性步骤,因此不应引起任何担忧或问题?
  • 让我们考虑一下,我正在编写一个函数 f,与此类似,它的返回类型因函数调用输入而异,并且这应该在运行前确定。为避免日后发生此类错误;编写此函数的最佳方法是什么?做类似 @typing.overload 的事情会更好吗?

  • 谢谢!

    最佳答案

    底层函数应该真正定义为一个重载——我可能会建议 Pandas 的补丁
    这是 looks like right now 的类型:

        def fillna(
    self: FrameOrSeries,
    value=None,
    method=None,
    axis=None,
    inplace: bool_t = False,
    limit=None,
    downcast=None,
    ) -> Optional[FrameOrSeries]: ...
    实际上,表示这一点的更好方法是使用 @overload —— 当 None 时,该函数返回 inplace = True :
        @overload
    def fillna(
    self: FrameOrSeries,
    value=None,
    method=None,
    axis=None,
    inplace: Literal[True] = False,
    limit=None,
    downcast=None,
    ) -> None: ...


    @overload
    def fillna(
    self: FrameOrSeries,
    value=None,
    method=None,
    axis=None,
    inplace: Literal[False] = False,
    limit=None,
    downcast=None,
    ) -> FrameOrSeries: ...


    def fillna(
    self: FrameOrSeries,
    value=None,
    method=None,
    axis=None,
    inplace: bool_t = False,
    limit=None,
    downcast=None,
    ) -> Optional[FrameOrSeries]:
    # actual implementation

    但假设你不能改变底层库,你有几种解包联合的方法。我专门为 re.match 制作了 a video about this 但我会在这里重申,因为它基本上是相同的问题( Optional[T] )
    选项 1:指示预期返回类型的断言
    assert 告诉类型检查器一些它不知道的东西:类型比它知道的要窄。 mypy 将信任此断言,并且类型将被假定为 pd.DataFrame
    def test_dummy() -> pd.DataFrame:
    df = pd.DataFrame()
    ret = df.fillna(df)
    assert ret is not None
    return ret
    选项 2:转换
    明确告诉类型检查器该类型是您所期望的,“抛弃” None -ness
    from typing import cast

    def test_dummy() -> pd.DataFrame:
    df = pd.DataFrame()
    ret = cast(pd.DataFrame, df.fillna(df))
    return ret
    类型:忽略
    (imo) hacky 解决方案是告诉类型检查器忽略不兼容性,我不建议使用这种方法,但它作为快速修复可能会有所帮助
    def test_dummy() -> pd.DataFrame:
    df = pd.DataFrame()
    ret = df.fillna(df)
    return ret # type: ignore

    关于python - 当内部函数返回可能是 'Union' 的 'None' 时,如何避免类型错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64896838/

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