首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使Mypy与多个混合器相互依赖?

如何使Mypy与多个混合器相互依赖?
EN

Stack Overflow用户
提问于 2019-12-12 20:05:01
回答 2查看 1.6K关注 0票数 4

目前在Electrum中,我们使用self来访问来自多个混合父类的方法。例如,QtPluginBase依赖于混合到HW_PluginBase的子类中才能工作。例如,有效的使用是class TrezorPlugin(QtPluginBase, HW_PluginBase)

这里有Qt gui,Kivy gui,还有CLI。虽然硬件钱包还没有为Kivy实现,但它们可能在将来实现。您可以在CLI上使用它们。

然而,也有多种硬件钱包制造商,都有自己的插件。

考虑Trezor + Qt:

对于Qt,我们有这样的类层次结构:

  • 使用的electrum.plugins.hw_wallet.qt.QtPluginBase
  • electrum.plugins.trezor.qt.QtPlugin(QtPluginBase)

对于Trezor,我们有:

  • 使用的electrum.plugin.BasePlugin
  • 使用的electrum.plugins.hw_wallet.plugin.HW_PluginBase(BasePlugin)
  • electrum.plugins.trezor.trezor.TrezorPlugin(HW_PluginBase)

并创建实际的Qt Trezor插件:

  • electrum.plugins.trezor.qt.Plugin(TrezorPlugin, QtPlugin)

关键是基gui中性插件将首先获得特定于制造商的方法,然后获得特定于gui的方法。

Aaron (在评论中)建议QtPluginBase可以子类HW_PluginBase,但这意味着特定于制造商的东西将出现在后面,这意味着产生的类不能被CLI或Kivy使用。

请注意,两者

electrum.plugins.trezor.trezor.TrezorPlugin(HW_PluginBase)

electrum.plugins.hw_wallet.qt.QtPluginBase

依赖HW_PluginBase。他们不能同时子类。

因此,如果我们避免混入,那么唯一的选择是要么拥有QtPluginBase子类TrezorPlugin (但有许多制造商),要么TrezorPlugin可以子类QtPluginBase,但是,同样,结果类不能被CLI或Kivy使用。

我意识到Union是一个“或”,所以这个暗示是没有意义的。但不存在Intersection类型。使用Union,大多数PyCharm功能都能工作。

如果QtPluginBase可以有一个类型--提示它可以子类为HW_PluginBase,但在运行时没有真正的子类,那就更好了。

如何在不对每个方法使用这种Union类型提示(因为每个方法都有self)的情况下使用Mypy输入?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-20 15:35:42

使用佩普-544 (Python )中添加的协议,您可以自己定义交叉接口!这还允许您在ClassA中隐藏不希望ClassB使用的实现细节。

代码语言:javascript
复制
from typing import Protocol

class InterfaceAB(Protocol):
    def method_a(self) -> None: ...
    def method_b(self) -> None: ...

class ClassA:
    def method_a(self) -> None:
        print("a")

class ClassB:
    def method_b(self: InterfaceAB) -> None:
        print("b")
        self.method_a()

# if I remove ClassA here, I get a type checking error!
class AB(ClassA, ClassB): pass

ab = AB()
ab.method_b()

# % mypy --version
# mypy 0.761
# % mypy mypy-protocol-demo.py
# Success: no issues found in 1 source file

对于这个文件的初始版本,可以归功于SomberNight/ghost43 43。

票数 4
EN

Stack Overflow用户

发布于 2019-12-24 11:37:17

由于类型尚未,您不能正确地键入self arg (并且Union不能代替它!)您可以做的是只为类型检查引入混合器基类。这是我在Django项目中使用mixins时经常使用的一个技巧。示例:

代码语言:javascript
复制
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .plugin import HW_PluginBase
    _Base = HW_PluginBase
else:
    _Base = object


class QtPluginBase(_Base):
    def load_wallet(self, wallet: 'Abstract_Wallet', window: ElectrumWindow):
        ...

现在可以删除self的显式类型,因为mypy可以推断出所有必需的基类本身。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59311963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档