Lisp的apply和funcall与Python的apply比较

2 投票
5 回答
5057 浏览
提问于 2025-04-16 04:58

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

仅作说明

自2.3版本起已不推荐使用:请改用带有 *args**keywords 的扩展调用语法。

在Python 3中已被移除。

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)

撰写回答