繁体   English   中英

可调用类的 Python 类型

[英]Python Typing for a Callable Class

我有类似的东西

class Class1(Class2):
    def __init__(
        self,
        use_class = Class3
        ...
    ):
         do something

所以Class1继承自Class2并且需要一个默认设置为Class3的参数use_class Class3接受floats和/或strings作为输入。 但是可以使用其他类来代替Class3 它们还接受floats和/或strings作为输入。 但是,它们都必须从同一个Class4继承。 此外,作为use_class有效输入的每个类都不会返回任何内容。 所以我对打字的猜测是

class Class1(Class2):
    def __init__(
        self,
        use_class: Callable[[Union[float, str]], None] = Class3
        ...
    ):
         do something

但这并没有包含这样一个事实,即作为use_class给出的类必须从Class4继承才能运行代码。 我在这里错过了什么吗? 我希望这个问题有意义,非常感谢任何帮助或指示。

我们可以做其中任何一个,但不能同时做。

为了要求它是 Class4 的子类,我们将Type用于标准的名义类型:

IsClass4 = Type[Class4]

并且要求值本身是一个可调用的接受某些输入,可以通过您建议的Callable或简单的Protocol结构类型来处理:

class MostlyWorks(Protocol):
    def __call__(self, value: float | str) -> Class4:
        ...

理想情况下,我们希望通过交集类型来实现这两者:

WhatWeWant = IsClass4 & AcceptsFloatsStrings

他们正在研究 PEP,但这需要一些时间。

对此有两个想法:Python 类型检查器通常非常松散甚至有问题,并且注释没有绝对规范的含义。 它们旨在捕捉现有代码库中的愚蠢错误,并使代码更具自我记录性。

这就是为什么我建议不要在注释兔子洞中走得太深。

第二个想法:想象类型检查器是一个相当昏暗的同事,如果你可以在不使用高级技术的情况下向类型检查器解释它,你的代码将是清晰易读的。

在这里,您混合了名义类型、结构类型,并且您需要一个Type[...]实例。 这是棘手的事情。

例如,假设您希望use_classClass4的子类,因此您可以在其上调用类方法。

如果我们不需要这是一个class怎么办? 如果它只是一个看起来像一个普通的旧 Python 对象怎么办:

class FakeClass(Protocol):
    def __call__(self, value: float | str) -> Class4:
        ...

    def works_like_classmethod(self, woah: Class77) -> str:
        ...

这让我们回到了一个相当标准的模式,并且明确地列出了你的代码将如何处理这件事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM