回调中可变数量的参数
Variable number of parameters in callback
我正在尝试在 Python 中实现一个回调系统,这类似于 JavaScript 可以在其回调中使用不同数量的参数。理想情况下,我想在我的回调参数中使用 *args
或 **kwargs
而无需 来实现此目的。
我的目标
我想要的是大致如下所示的内容:
def callback1(val):
print(val)
def callback2(x, y):
print(x, y)
def callback3(a, b, c):
print(a, b, c)
def foo(callback):
callback(1, 2, 3) # Always has 3 arguments to pass
foo(callback1) # Fails. Should print "1"
foo(callback2) # Fails. Should print "1 2"
foo(callback3) # Ok. Prints "1 2 3"
也许更详细的表达方式是:
# num_params() method isn't real (that I know of), but this is an
# inelegant example of how the callbacks might work if it were
def foo2(callback):
if num_params(callback) == 1:
callback(1)
elif num_params(callback) == 2:
callback(1, 2)
elif num_params(callback) == 3:
callback(1, 2, 3)
我不想要的
我不想在每个回调中使用 *args
或 **kwargs
(除非这是不可能的任何其他方式),如下所示:
# This is just SO ugly
def callback1(*args):
print(args[0])
def callback2(*args):
print(args[0], args[1])
def callback3(*args):
print(args[0], args[1], args[2])
JavaScript 等价
这在JavaScript中比较常见。例如,可以为 .forEach()
函数的回调提供 1、2 或 3 个参数:
let myArray = [1, 2, 3, 4]
// Valid
myArray.forEach((element) => {
// Do stuff with the element only
});
// Valid
myArray.forEach((element, index) => {
// Do stuff with the element AND the index
});
// Valid
myArray.forEach((element, index, array) => {
// Do stuff with the element, index and the whole array
});
然而,尽管我在 Google 搜索中尽了最大努力,但我不知道如何在 Python 中实现它(甚至在 JavaScript 中,但那是点;我希望这不会回来咬我)。
我非常想知道这在 Python and/or 中是否可行 and/or 这种编码技术的正确术语是什么。
您可以使用相同数量的参数定义所有回调函数,即:
def callback1(val, b=None, c=None):
print(val)
def callback2(x, y, c=None):
print(x, y)
def callback3(a, b, c):
print(a, b, c)
或者您可以在函数内解压 *args
:
def callback1(*args):
val, _, _ = args
print(val)
def callback2(*args):
x, y, _ = args
print(x, y)
def callback3(*args):
a, b, c = args
print(a, b, c)
最后,您可以使用 functools.partial
发挥创意。
args 和 kwargs 有什么问题?这是做到这一点的pythonic方式。 Python 不是 JavaScript。如果您不喜欢通过 args[0]
、args[1]
等索引访问 args,您可以像往常一样定义一些 args,然后休息(未使用的 args)- 在 *args
:
def callback1(a, *args):
print(a)
def callback2(a, b, *args):
print(a, b)
def callback3(a, b, c):
print(a, b, c)
你也可以在函数中解压它们:
def callback1(*args):
a, *rest = args
print(a)
它使内部更加冗长,但所有回调的定义相同。
命名变量也很常见,您不会使用 _
(下划线)代替 args
、rest
等:
def callback1(a, *_):
print(a)
def callback1(*args):
a, *_ = args
print(a)
我正在尝试在 Python 中实现一个回调系统,这类似于 JavaScript 可以在其回调中使用不同数量的参数。理想情况下,我想在我的回调参数中使用 *args
或 **kwargs
而无需 来实现此目的。
我的目标
我想要的是大致如下所示的内容:
def callback1(val):
print(val)
def callback2(x, y):
print(x, y)
def callback3(a, b, c):
print(a, b, c)
def foo(callback):
callback(1, 2, 3) # Always has 3 arguments to pass
foo(callback1) # Fails. Should print "1"
foo(callback2) # Fails. Should print "1 2"
foo(callback3) # Ok. Prints "1 2 3"
也许更详细的表达方式是:
# num_params() method isn't real (that I know of), but this is an
# inelegant example of how the callbacks might work if it were
def foo2(callback):
if num_params(callback) == 1:
callback(1)
elif num_params(callback) == 2:
callback(1, 2)
elif num_params(callback) == 3:
callback(1, 2, 3)
我不想要的
我不想在每个回调中使用 *args
或 **kwargs
(除非这是不可能的任何其他方式),如下所示:
# This is just SO ugly
def callback1(*args):
print(args[0])
def callback2(*args):
print(args[0], args[1])
def callback3(*args):
print(args[0], args[1], args[2])
JavaScript 等价
这在JavaScript中比较常见。例如,可以为 .forEach()
函数的回调提供 1、2 或 3 个参数:
let myArray = [1, 2, 3, 4]
// Valid
myArray.forEach((element) => {
// Do stuff with the element only
});
// Valid
myArray.forEach((element, index) => {
// Do stuff with the element AND the index
});
// Valid
myArray.forEach((element, index, array) => {
// Do stuff with the element, index and the whole array
});
然而,尽管我在 Google 搜索中尽了最大努力,但我不知道如何在 Python 中实现它(甚至在 JavaScript 中,但那是点;我希望这不会回来咬我)。
我非常想知道这在 Python and/or 中是否可行 and/or 这种编码技术的正确术语是什么。
您可以使用相同数量的参数定义所有回调函数,即:
def callback1(val, b=None, c=None):
print(val)
def callback2(x, y, c=None):
print(x, y)
def callback3(a, b, c):
print(a, b, c)
或者您可以在函数内解压 *args
:
def callback1(*args):
val, _, _ = args
print(val)
def callback2(*args):
x, y, _ = args
print(x, y)
def callback3(*args):
a, b, c = args
print(a, b, c)
最后,您可以使用 functools.partial
发挥创意。
args 和 kwargs 有什么问题?这是做到这一点的pythonic方式。 Python 不是 JavaScript。如果您不喜欢通过 args[0]
、args[1]
等索引访问 args,您可以像往常一样定义一些 args,然后休息(未使用的 args)- 在 *args
:
def callback1(a, *args):
print(a)
def callback2(a, b, *args):
print(a, b)
def callback3(a, b, c):
print(a, b, c)
你也可以在函数中解压它们:
def callback1(*args):
a, *rest = args
print(a)
它使内部更加冗长,但所有回调的定义相同。
命名变量也很常见,您不会使用 _
(下划线)代替 args
、rest
等:
def callback1(a, *_):
print(a)
def callback1(*args):
a, *_ = args
print(a)