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何かをしたい、または作成したいと思っていましたlambdafuncとは、シンボルではなく関数g内のクロージャ変数であるため、またはのバインディングが異なる環境から呼び出した場合でも、 の定義環境の変数が使用されます。lambdaafuncga

于 2013-08-15T19:32:53.663 に答える
4

evalLisp と 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無名関数用の特別な形式がありますが、それらは 1 つの式に制限されており、ステートメントを含めることはできません。代わりに、ローカルで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 には構文の制限があり、クローズド オーバー変数は読み取り専用です。これは、関数に代入 (または拡張代入) がある場合、2 つの可能性しかないためです。

  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 に答える