代码之家  ›  专栏  ›  技术社区  ›  Tim McNamara

什么时候使用“呼叫”是个好主意?

  •  15
  • Tim McNamara  · 技术社区  · 14 年前

    人们对使用 __call__ . 我很少看到它被使用,但我认为当您知道某个类将被用于某些默认行为时,它是一个非常方便的工具。

    4 回复  |  直到 14 年前
        1
  •  16
  •   Owen S.    14 年前

    我认为你的直觉是对的。

    历史上,可调用对象(或者我有时听说过的“函数”)在OO世界中被用来模拟闭包。在C++中,它们经常是必不可少的。

    然而, __call__ 在Python世界中有相当多的竞争:

    • 一种规则命名的方法,其行为有时可以更容易地从名称中推导出来。无法转换为绑定方法,该方法可以像函数一样调用。
    • 通过返回嵌套块中定义的函数获得的闭包。
    • 一个lambda,它是一种有限但快速的关闭方法。
    • 生成器和协程器,它们的身体像函数一样保持累积状态。

    我想说是时候用了 阿尔卡拉尔 当你没有更好的服务于上述的选择之一。请检查以下标准:

    • 对象具有状态。
    • 你的班级有一个明确的“主要”行为,这有点愚蠢。例如,如果你发现自己在写作 run() doStuff() go() 或是曾经受欢迎和多余的 doRun() ,你可能有一个候选人。
    • 对象的状态超出了对生成器函数的预期。
    • 对象包装、模拟或抽象函数的概念。
    • 您的对象还有其他辅助方法,这些方法在概念上属于您的主要行为。

    我喜欢的一个例子是UI命令对象。他们的主要任务是执行命令和,但是使用额外的方法来控制它们作为菜单项的显示,例如,在我看来,这是您仍然希望调用对象的类型。

        2
  •  4
  •   John La Rooy    14 年前

    如果需要对象可调用,就使用它,这就是它的作用所在。

    我不知道你所说的违约行为是什么意思

    我发现它特别有用的一个地方是,当使用包装器或其他类似的东西时,对象被称为深入到某个框架/库中。

        3
  •  1
  •   Katriel    14 年前

    一般来说,python有一个 许多 双下划线方法。它们的存在是有原因的:它们是以Python方式重载运算符。例如,如果你想要一个新的类,在这个类中,我不知道,打印 "foo" ,您定义 __add__ __radd__ 方法。这没有什么本质上的好或坏,只是有什么好或坏关于使用 for 循环。

    事实上,使用 __call__ 通常是更像蟒蛇式的方法,因为它鼓励代码的清晰性。你可以替换 MyCalculator.calculateValues( foo ) 具有 MyCalculator( foo ) 比如说。

        4
  •  0
  •   Daniel Kluev    14 年前

    它通常在类与一些实例上下文一起用作函数时使用,例如某些decoratorclass将用作 @DecoratorClass('some param') ,因此“some param”将存储在实例的命名空间中,然后将实例作为实际的装饰器调用。

    当您的类提供一些不同的方法时,它不是很有用,因为它通常不明显调用会做什么,而且在这些情况下显式比隐式要好。