Pythonic方法参数化一个函数(没有lambda)

dkv*_*dkv 3 python lambda function

这是关于编程风格的问题:参数化函数的最"Pythonic"方式是什么(即使是正确的单词呢?)

假设我有一个函数(例如ODE求解器)接受两个参数的另一个函数(例如ODE本身)作为参数.

def solver(fun):
   # Implementation goes here
   # fun is a function handle that accepts two args e.g. fun(t,y)
Run Code Online (Sandbox Code Playgroud)

但是,我希望传递solver的函数由第三个值参数化

def myFun(t,y,A):
   # Implementation goes here
Run Code Online (Sandbox Code Playgroud)

我一直在使用以下lambda函数处理这种情况:

A = 4
solution = solver(lambda t,y:myFun(t,y,A))
Run Code Online (Sandbox Code Playgroud)

我最近在网上看到一些帖子告诉我要避免lambda像瘟疫那样,而且Guido自己后悔允许这个功能.如果lambdas确实很糟糕,那么实施上述方法的"Pythonic"方法有哪些?没有lambda我遇到无法访问全局命名空间的问题,即我想这样做:

A = 4
def myFunNotLambda(t,y):
    return myFun(t,y,A)
solution = solver(myFunNotLambda)
Run Code Online (Sandbox Code Playgroud)

但实现这一目标的唯一方法似乎是制作A全球,这绝对比使用更糟糕lambda

Wil*_*sem 5

您可以使用functools.partial它,例如:

from functools import partial

A = 4
solution = solver(partial(myFun,A=A))
Run Code Online (Sandbox Code Playgroud)

partial(..)给定一个函数的构造(这里myFunc)另一个函数,其中A参数现在具有默认值A.

  • @dkv`partt`返回一个完整的callable(看起来像一个类的实例).它只会在调用者传入时由调用者构造.如果你有一个循环有很多迭代,那么你需要担心的是调用时间.那就是说,我认为你在谈论微观优化.我会对它进行分析,看看它是否首先出现问题. (3认同)
  • @dkv'partial`对象的构造是一次性成本,一旦构造它就不需要再次构造,除非你需要一个具有不同`A`参数的新构件.但是当你调用部分对象时,它必须调用原始的`myFun`,因此你得到两个级别的Python函数/方法调用,就像在基于lambda的解决方案中一样. (3认同)
  • @dkv:构建还是调用?因为通常构建只发生一次因此并不重要.[这个答案](/sf/answers/827994261/)表明partial比lambda快. (2认同)