5

在 python 中,引号运算符的等价物是什么?我发现需要延迟评估。例如,假设在下面的 lisp 伪代码中我有:

a = '(func, 'g)
g = something
(eval a)

我正在做的是将评估推迟g到以后。这是必要的,因为我想g稍后定义。这个伪代码在python中的等效思想是什么?

4

2 回答 2

8
a = lambda: func(g)
g = something
a()

这不是最直接的翻译——最直接的翻译会使用一个字符串和eval——但它可能是最合适的。无论如何,引用可能不是您在 Lisp 中想要的。您可能想要delay做某事或创建一个lambda. 请注意,funcandglambda函数中的闭包变量,而不是符号,因此如果您a从具有不同绑定的环境调用funcor g,它仍将使用来自a定义环境的变量。

于 2013-08-15T19:32:53.663 回答
4

在Lispeval和 Python 中,用于延迟评估都是不好的。

在 Python 和 Lisp 中,您可以使用闭包延迟评估:

def print_it(x):
    def f():
        print g(x)
    return f

f = print_it(42)

def g(x):
   return x * x

f()

请注意,闭包中捕获的不是变量的,而是变量本身,这有时令人惊讶:

fa = []

for x in range(10):
    def g():
        print x
    fa.append(g)

for f in fa:
    f() # all of them will print 9

x = 42

fa[0]() # the output will be 42

要解决这个问题(Common Lisp 中也可能存在),您可能会看到如下内容:

for x in range(10):
    def g(x = x):
        print x
    fa.append(g)

或(在 CL 中)之类的东西

(let ((a a))
  (lambda () (print a)))

Python 也有lambda匿名函数的特殊形式,但它们仅限于一个表达式,不能包含任何语句。相反,本地def函数是没有任何限制的常规函数​​。

for x in range(10):
    # print is a statement in Python 2.x and cannot be in a lambda
    fa.append(lambda x=x: sys.stdout.write(str(x) + "\n"))

最后,Python 2.x 有语法限制,封闭变量是只读的,因为如果函数中有赋值(或扩充赋值),则只有两种可能性:

  1. 该变量是一个全局变量(并且之前已用 声明过global x
  2. 变量是局部的

特别是排除了被分配的变量可能是封闭函数范围的局部变量。

Python 3.x 通过提供新的可能声明消除了这个限制nonlocal x,现在这个著名的adder例子可以实现为

def adder(x):
    def f(y):
        nonlocal x
        x += y
        return x
    return f
于 2013-08-17T20:09:20.953 回答