python - 如果 mixin 的目标类继承自元类,如何键入提示 mixins?
问题描述
考虑以下类和 mixin:
class Target(ClassThatUsesAMetaclass):
def foo(self):
pass
class Mixin:
def __init__(self):
self.foo() # type error: type checker doesn't know Mixin will have
# access to foo once in use.
class Combined(Mixin, Target):
def __init__(self):
Target.__init__(self)
Mixin.__init__(self)
我试图避免上述场景中的类型检查器错误。一种选择是:
from typing import Protocol
class Fooable(Protocol):
def foo(self): ...
class Mixin(Fooable):
def __init__(self):
self.foo()
本来会很好用,除了Target
继承自使用元类的类,因此Combined
不能同时继承Target
和Mixin
。所以现在我正在尝试另一种方法,self
注释Mixin
:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .this import Mixin, Target
Mixin_T = type('Mixin_T', (Mixin, Target), {})
class Mixin:
def __init__(self: Mixin_T):
self.foo() # No longer an error
class Combined(Mixin, Target):
def __init__(self):
Target.__init__(self)
Mixin.__init__(self) # Now this is an error: "Type[Mixin]" is not
# assignable to parameter "self"
# "Mixin" is incompatible with "Mixin_T"
那么除了使用之外我应该如何赢得这个# type: ignore
呢?
解决方案
除此之外,除了提供一些说明之外,上面几乎没有代码和一些错误概念使这个问题根本无法回答。
首先,您确定您是“从元类继承”吗?除非创建另一个元类,否则继承一个元类是没有意义的。您的片段显示您从假定的元类(没有给出代码)中继承,以创建 Target
并尝试将它们Target
用作普通类(非元类)的父类。这是没有意义的。
您可能只是混淆了这些术语,隐藏InheritFromMetaclass
类实际上只是使用元类,而不是从它“继承”。那么您的问题根本与元类无关。
所以,片段中真正可见的问题是静态检查器没有“看到” self.foo
Mixin 类中的方法 - 你猜怎么着?没有方法- 检查器只是在你面前抛出一个冷酷的事实:虽然 Python 确实允许引用类中不可 用的方法和属性,但知道它将与其他具有这些属性的类一起使用,这不是好的设计并且容易出错。那种糟糕的设计静态类型检查存在被淘汰。self.foo
Mixin
所以,你需要的Mixin
是一个抽象类的基础,并Foo
作为一个抽象方法。(或者Mixin
本身就是那个抽象类)。
如果 - 由于使用其他元类,由于元类冲突,您不能继承 Mixin abc.ABC
,您必须:从 with 实际使用的元类创建一个组合元类,然后将InheritsFromMetaclass
其ABCMeta
用作元类Mixin
- 或者只是创建一个存根foo
方法按Mixin
原样(这可能会引发NotImplementedError
- 因此具有与抽象方法相同的行为,但实际上不必从它继承。
重要的部分是你在类体内的代码中访问的方法和属性必须存在于该类中,而不依赖于它的子类中存在的属性。
如果这不能解决您的问题,您需要提供更多数据 - 包括涉及您的实际元类的可重现的完整示例。(并且它可以通过组合上面提到的元类来解决)
推荐阅读
- amazon-web-services - AWS 使用 Cloudfront 增强托管性能
- python - pyplot:在轴上添加点投影
- flutter - 如何用颤动的条子做动画切换器
- android - 我的设备脱机并显示脱机反应本机但已连接到笔记本电脑
- php - Laravel Livewire 计算器/键盘,提高输入显示速度
- python - discord.py:隐藏所有其他用户的消息,但@提及用户
- c# - Try...catch 在执行存储过程时不起作用
- java - 如何编写自定义比较器以使用 SimpleEntry 对树集进行排序?
- algorithm - 这个大 O 评估是否正确?
- c - C: 你应该为要传递给 strcpy 的字符串数组分配多大的大小,然后将其复制到。?