Lisp的apply和funcall与Python的apply比较
Lisp中的APPLY是用来调用函数的,它可以把存储在列表里的参数计算出来并传给函数。(这个说法是改编自Rainer的评论)
举个例子,下面的代码把(list 1 2 3)变成了(+ 1 2 3)。
(apply #'+ '(1 2 3))
不过,Python的apply功能和Lisp的funcall类似,只是有一些小的区别(输入是以元组或列表的形式给出的)。
(defun add (x y) (+ x y)) (funcall #'add 1 2) or (funcall #'(lambda (x y) (+ x y)) 10 2)
apply(lambda x,y : x+y, [1,2])
你觉得怎么样?Lisp的funcall和Python的apply之间还有更多的区别吗?
5 个回答
2
4
在Common Lisp中,(funcall #'fun 1 (list 2 3 4))
和 (fun 1 (list 2 3 4))
是完全一样的,意思是调用函数fun,并传入参数1和一个包含2、3、4的列表。而(apply #'fun 1 (list 2 3 4))
的意思就不一样了,这取决于函数fun需要多少个参数。
* (defun bleargh (a &rest b) (cons a b))
BLEARGH
* (funcall #'bleargh 1 (list 1 2 3))
(1 (1 2 3))
* (apply #'bleargh 1 (list 1 2 3))
(1 1 2 3)
所以,FUNCALL和APPLY的作用是完全不同的。
8
有没有什么特别的原因让Python选择用apply这个名字,而不是funcall呢?
因为这是Python,不是LISP。没必要用一样的名字,funcall
是LISP里的一个命令,而apply
在Python里是个不同的东西。
不过要注意,apply
在Python中已经不推荐使用了,建议用扩展调用语法。
旧的语法:
apply(foo, args, kwargs)
新的语法:
foo(*args, **kwargs)