如何键入对象方法的返回值以跟随其在 init 期间接收到的函数?

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

这是一个 Python 类型提示问题,但我认为在我们了解问题的症结之前,了解一些上下文会有所帮助。

我有一个接受两个参数的类:

  1. 信号 - 这是由外部客户“发出”的信号。
  2. 插槽 - 这与发射时执行的信号连接。

您可以通过执行

Signal.connect(Slot)
将两者连接起来。此连接将持续存在,直到您再次显式断开连接,并且该插槽将在每次发出信号时执行。 (对于熟悉的人来说,这是 Qt PySide2 库)。我正在构建一个对象,确保该插槽仅在第一次发出时执行一次,然后与信号断开连接,但我正在努力正确地键入两个 mypy 错误提示:

import typing as _t

from Qt import QtCore as _QtCore

_R = _t.TypeVar("_R")


class SingleShotConnect:
    _INSTANCES: _t.ClassVar[_t.Set["SingleShotConnect"]] = set()

    def __init__(
        self,
        signal: "_QtCore.SignalInstance",
        slot: _t.Callable[..., _R],
    ) -> None:
        self._signal = signal
        self._slot = slot
        self._signal.connect(self._single_shot_wrapper)
        SingleShotConnect._INSTANCES.add(self)

    # error: A function returning TypeVar should receive at least one argument containing the same TypeVar  [type-var]
    def _single_shot_wrapper(self, *args, **kwargs) -> _R:
        self._signal.disconnect(self._single_shot_wrapper)
        SingleShotConnect._INSTANCES.remove(self)

        # error: Incompatible return value type (got "_R@__init__", expected "_R@_single_shot_wrapper")
        return self._slot(*args, **kwargs)

如您所见,有两个与

_single_shot_wrapper()
相关的错误,我不知道如何修复?由于 python 版本限制,如果这是一个可能的解决方案,我无法访问 ParamSpec。

python qt python-typing mypy
1个回答
0
投票

该类在

_R
中必须是通用的,以便
__init__
绑定的类型可用于
_single_shot_wrapper

import typing as _t

from Qt import QtCore as _QtCore

_R = _t.TypeVar("_R")


class SingleShotConnect(_t.Generic[_R]):
    # Might want SingleShotConnect[_R] here; did not test if
    # necessary
    _INSTANCES: _t.ClassVar[_t.Set["SingleShotConnect"]] = set()

    def __init__(
        self,
        signal: "_QtCore.SignalInstance",
        slot: _t.Callable[..., _R],
    ) -> None:
        self._signal = signal
        self._slot = slot
        self._signal.connect(self._single_shot_wrapper)
        SingleShotConnect._INSTANCES.add(self)

    # error: A function returning TypeVar should receive at least one argument containing the same TypeVar  [type-var]
    def _single_shot_wrapper(self, *args, **kwargs) -> _R:
        self._signal.disconnect(self._single_shot_wrapper)
        SingleShotConnect._INSTANCES.remove(self)

        # error: Incompatible return value type (got "_R@__init__", expected "_R@_single_shot_wrapper")
        return self._slot(*args, **kwargs)
© www.soinside.com 2019 - 2024. All rights reserved.