目前在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.QtPluginBaseelectrum.plugins.trezor.qt.QtPlugin(QtPluginBase)对于Trezor,我们有:
electrum.plugin.BasePluginelectrum.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输入?
发布于 2020-02-20 15:35:42
使用佩普-544 (Python )中添加的协议,您可以自己定义交叉接口!这还允许您在ClassA中隐藏不希望ClassB使用的实现细节。
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。
发布于 2019-12-24 11:37:17
由于类型尚未,您不能正确地键入self arg (并且Union不能代替它!)您可以做的是只为类型检查引入混合器基类。这是我在Django项目中使用mixins时经常使用的一个技巧。示例:
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可以推断出所有必需的基类本身。
https://stackoverflow.com/questions/59311963
复制相似问题