如何将参数绑定到 Python 中的函数?
如何将参数绑定到 Python 函数,以便稍后可以在不使用参数(或使用较少的附加参数)的情况下调用它?
例如:
def add(x, y):
return x + y
add_5 = magic_function(add, 5)
assert add_5(3) == 8
我这里需要什么magic_function
?
在框架和库中,人们经常会在尝试向回调提供参数时意外地立即调用函数:例如 on_event(action(foo))
。 解决方案是使用此处描述的技术之一将 foo
作为参数绑定到 action
。 例如,请参阅 如何将参数传递给 Tkinter 中的 Button 命令? 和 在 Python 中使用字典作为 switch 语句。
但是,某些 API 允许您单独传递要绑定的参数,并执行绑定为你。 值得注意的是,标准库中的线程 API 就是这样工作的。 请参阅线程在调用 Thread.start 之前开始运行。 如果您尝试像这样设置自己的 API,请参阅如何编写简单的回调函数?。
显式绑定参数也是避免使用闭包时后期绑定引起问题的一种方法。 例如,for
循环或列表理解中的 lambda
会产生计算相同结果的单独函数,从而产生此问题。 请参阅 lambda 函数闭包捕获什么? 和 在循环(或推导式)中创建函数(或 lambda)。
How can I bind arguments to a Python function so that I can call it later without arguments (or with fewer additional arguments)?
For example:
def add(x, y):
return x + y
add_5 = magic_function(add, 5)
assert add_5(3) == 8
What is the magic_function
I need here?
It often happens with frameworks and libraries that people accidentally call a function immediately when trying to give arguments to a callback: for example on_event(action(foo))
. The solution is to bind foo
as an argument to action
, using one of the techniques described here. See for example How to pass arguments to a Button command in Tkinter? and Using a dictionary as a switch statement in Python.
Some APIs, however, allow you to pass the to-be-bound arguments separately, and will do the binding for you. Notably, the threading API in the standard library works this way. See thread starts running before calling Thread.start. If you are trying to set up your own API like this, see How can I write a simple callback function?.
Explicitly binding arguments is also a way to avoid problems caused by late binding when using closures. This is the problem where, for example, a lambda
inside a for
loop or list comprehension produces separate functions that compute the same result. See What do lambda function closures capture? and Creating functions (or lambdas) in a loop (or comprehension).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
functools .partial
返回一个可调用的包装函数,其中部分或全部参数被冻结。上面的用法相当于下面的
lambda
。functools.partial
returns a callable wrapping a function with some or all of the arguments frozen.The above usage is equivalent to the following
lambda
.使用
functools.partial
:Using
functools.partial
:如果 functools.partial 不可用,那么可以轻松模拟它:
或者
If
functools.partial
is not available then it can be easily emulated:Or
lambda
允许您使用更少的参数创建一个新的未命名函数并调用该函数:您还可以使用
functools.partial
。 如果您计划在函数调用中使用命名参数绑定,这也适用:请注意,如果您从左侧绑定参数,则需要按名称调用参数。 如果从右侧绑定,它会按预期工作。
lambda
s allow you to create a new unnamed function with fewer arguments and call the function:You can also use
functools.partial
. If you are planning to use named argument binding in the function call this is also applicable:Note that if you bind arguments from the left you need to call the arguments by name. If you bind from the right it works as expected.
这也可以工作:
This would work, too:
在 Python 中函子可以这样定义。 它们是可调用的对象。 “绑定”仅设置参数值。
你可以做类似的事情
Functors can be defined this way in Python. They're callable objects. The "binding" merely sets argument values.
You can do things like
该问题一般询问有关绑定参数的问题,但所有答案都与函数有关。 如果您想知道,
partial
也适用于类构造函数(即使用类而不是函数作为第一个参数),这对于工厂类很有用。 您可以按如下方式进行操作:The question asks generally about binding arguments, but all answers are about functions. In case you are wondering,
partial
also works with class constructors (i.e. using a class instead of a function as a first argument), which can be useful for factory classes. You can do it as follows: