如何在python中继承类型提示?

时间:2017-12-19 22:45:04

标签: python inheritance python-3.5 type-hinting mypy

所以我的问题是当我有一个类A的类来做事情并且我将这些函数用作子类(B)时,它们仍然为类A键入,并且不接受我的类B对象作为参数或函数签名。

我的问题简化了:

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div class="container">
    <div class="nav-bar">
      <button data-bind="click: startLoading">Start loading</button>
      <button data-bind="click: stopLoading">Stop loading</button>
    </div>
    <div class="content">
      <div class="tab-content">
        <!-- ko if: tabLoading -->
        <div class="tab-loading-mask" id="tab-loading-mask-edit"></div>
        <!-- /ko -->
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
          It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with
          desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
      </div>
    </div>
  </div>
</body>

我也可以提供完整的信号类,但这会分散注意力。这让我在mypy中出现一个错误 - &gt;错误:参数1到&#34;连接&#34; &#34;信号&#34;具有不兼容的类型Callable [[B],None];预期可调用[[A],无]

由于信号处理在A中实现,子类B不能期望返回B类型的对象,即使它显然应该没问题......

3 个答案:

答案 0 :(得分:0)

类型提示错误完全正确。您使用Signal A方法__init__创建了Aself.signal = Signal[A]() 实例作为类型:

Signal

传入子类很好,但是现在所有与A实例交互的代码只能用于handle_b()个实例。另一方面,B需要A的实例,而不能将要求降低到self.signal = Signal()

删除约束:

$hdtcount=mysql_num_rows(mysql_query("SELECT * FROM helpdesk WHERE replied='0'"));
?>

<a href="HelpDeskA.php">
    Answer Tickets<?php
    if($hdtcount>="1"){ echo "<font color=cyan>($hdtcount)</font>"; }
    ?>
</a>
<?php
}
?>

<a href="faqs.php">
    FAQ
</a>


<a href="ipsharing.php">
    IP-Sharing
</a>

或在每个子类中使用正确的类型创建实例。

答案 1 :(得分:0)

from __future__ import annotations
from typing import TypeVar, Generic, Callable

T = TypeVar('T')


class Signal(Generic[T]):
    def connect(self, connector: Callable[[T], None]) -> None:
        pass

    def emit(self, payload: T):
        pass


class A(Generic[T]):
    def __init__(self) -> None:
        self.signal = Signal[T]()

    def do(self: A) -> None:
        self.signal.emit(self)


def handle_b(b: B) -> None:
    print(b.something)


class C:
    pass


def handle_c(c: C) -> None:
    print(c)


class B(A[B]):
    def __init__(self) -> None:
        super().__init__()
        self.signal.connect(handle_b)  # OK
        self.signal.connect(handle_c)  # incompatible type

    @property
    def something(self) -> int:
        return 42

答案 2 :(得分:0)

传递给connector的{​​{1}}的类型为Signal[A],这意味着它必须承诺能够处理Callable[[A], None]的任何实例(或其任何子对象-类)。 A无法实现此承诺,因为它仅适用于handle_b的实例,因此不能用作类型B的{​​{1}}的{​​{1}}。

假定connector的任何实例的signal的{​​{1}}只会被要求处理Signal[A]的实例,因此不需要类型为connector,但是signal就足够了。这意味着B的类型不是固定的,但是根据B的不同子类而有所不同,这意味着Signal[A]需要通用。

The answer by ogurets正确地使Signal[B]通用,但是signal并没有问题,因为尚不清楚A是否属于A的类型。我们可以保证通过使用A所使用的相同类型变量注释do来匹配这些类型。通过使用受self约束的新类型变量self.signal.emit,我们告诉mypy self将始终是Signal的子类型,因此具有属性{{1} }。

_A