可调用实例参数的表示法是啥?

Posted

技术标签:

【中文标题】可调用实例参数的表示法是啥?【英文标题】:What is the notation for a callable instance parameter?可调用实例参数的表示法是什么? 【发布时间】:2021-05-25 06:47:23 【问题描述】:

我正在尝试寻找最优雅的方式来帮助 IntelliSense 捕获可调用对象的预期参数集。

考虑以下代码:

class Box:
    def __init__(self, f: callable) -> None:
        self.f: callable = f

    def callF(self):
        self.f(self, 5, 6, 77, 65)

可以看到,可调用对象f 没有在参数中明确定义。

我可以尝试通过委托解决它:

from __future__ import annotations

class Box:

    class BoxFDelegate:
        def f(self, a:int, b:int, c:int, d:int):
            pass

    def __init__(self, f: Box.BoxFDelegate.f) -> None:
        self.f: Box.BoxFDelegate.f = f

    def callF(self):
        self.f(self, 5, 6, 77, 65)

委托模式很棒,但它需要在代码主体的其他地方子类化委托:

class D(Box.BoxFDelegate):
    def f(self, a:int, b:int, c:int, d:int):
        ...

class Main:
    def boxing():
        boxDelegate = D()
        box = Box(boxDelegate)
        ...

作为委托的一种可能变体,是将委托方法包含在 Main 类中:

class Main(Box.BoxFDelegate):
    def boxing():
        box = Box(self.f)
        ...

    def f(self, a:int, b:int, c:int, d:int):
        ...

这种表示法更短,但如果我有许多不同的类 Box 实例怎么办?

在完美的世界中,我可以通过以下方式完成这样的问题:

class Main(Box.BoxFDelegate):
    def boxing():
        boxes = [
                    Box(lambda a, b, c, d: ...),
                    Box(lambda a, b, c, d: ...),
                    Box(lambda a, b, c, d: ...),
                ]

不幸的是,这种方式是只写的。

如何在类型上做到简洁,不被以后会尝试维护代码的开发者狠狠地打?

【问题讨论】:

__doc__ 不是重点! 你用的是什么版本的python? 查看 typing.Callable 【参考方案1】:

请看@SuperStormer 的评论。结果应该是这样的:

from __future__ import annotations
from typing import Callable


class Box:
    def __init__(self, f: Callable[[Box, int, int, int, int], None]) -> None:
        self.f = f

    def call_f(self) -> None:
        self.f(self, 5, 6, 77, 65)

【讨论】:

以上是关于可调用实例参数的表示法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

调用表达式中可调用参数的完美转发的目的?

python 装饰器总结

可调用语句 - PostgreSQL - 多个输出参数

如何使用HttpClient

Firebase 可调用函数未接收参数

三.python高级