【问题标题】:python equivalent of quote in lisppython相当于lisp中的引号
【发布时间】:2013-08-15 19:31:28
【问题描述】:

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

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

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

【问题讨论】:

  • 通常,如果您尝试将某些内容翻译成 Python,并且不知道如何去做,那么您正在做一些非常不符合 Python 的事情,并且需要退后一步才能找到Pythonic 方式来做你真正想做的事情。特别是,任何使用eval 的代码可能一开始就不应该编写。
  • 我肯定会在接下来的几天里尝试切换到 clojure...
  • 老实说,即使在 Lisp 中,eval不是延迟表达式求值的正确方法。通常,您将表达式包装在 lambda 中并稍后调用它。 Scheme 还提供了delay/force,它提供了lambda 的结果的记忆。

标签: python functional-programming lisp quote


【解决方案1】:
a = lambda: func(g)
g = something
a()

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

【讨论】:

  • +1 正如我对 OP 所提到的,即使在 Lisp 中,eval 也是大多数问题的错误答案,包括延迟评估。 (编辑:你刚刚做了一个编辑说同样的话。:-D)
  • 注意python也有promise/delay库。
【解决方案2】:

在 Lisp 和 Python 中,使用 eval 延迟评估是不好的。

在 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-ined 函数是一个没有任何限制的常规函数​​。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-14
    • 2021-03-14
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-07
    相关资源
    最近更新 更多