[英]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_class
是Class4
的子类,因此您可以在其上调用类方法。
如果我们不需要这是一个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.