python闭包未正确封装值

时间:2019-01-08 13:54:24

标签: python-3.x closures

我的背景有点小,目前正在使用python。我习惯于在构造过程中使用封闭的方法封装使用过的参数,从而在执行时使用该值。

因此,我对以下poc感到困惑:

class Test():

    def __init__(self, number):
        self._test = number


l = list()
l2 = list()


l = [Test(1), Test(2), Test(3)]


def python_is_weird(elem):
    a = elem
    print(a._test)


for e in l:
    print(e._test)
    l2.append(lambda _ : python_is_weird(e))


for l in l2:
    l(None)

输出为:

1
2
3
3
3
3

应为:

1
2
3
1
2
3

为了确保这不是让我发疯的事情,我在常见的lisp中写了相同的poc:

(defclass Test ()
  ((test :initarg :test
         :reader test)))

(defparameter *l* (list (make-instance 'test :test 1)
                        (make-instance 'test :test 2)
                        (make-instance 'test :test 3)))

(defparameter *l2* (list))

(defun lisp_is_not_weird (elem)
  (let ((a elem))
    (FORMAT T "~a~%" (slot-value a 'test))))

(dolist (var *l*)
  (FORMAT T "~a~%" (slot-value var 'test))
  (push (lambda (ignore)
          (declare (ignore ignore))
          (lisp_is_not_weird var))
        *l2*))

(dolist (l *l2*)
  (funcall l nil))

和预期的输出:

1
2
3
3
2
1

为什么python的行为如此奇怪,我如何才能从普通的Lisp中获得与我习惯的相同的行为?

0 个答案:

没有答案