簡體   English   中英

Python3:將遞歸 function 注入到 function 中的 exec() 中

[英]Python3: inject a recursive function into exec() in a function

在 python3 中,如果將帶有遞歸調用的 function 注入到 function 中的exec()中,則會出現錯誤。 例如,下面的代碼

def B(pys):
    exec(pys)

pys="""
def fibonacci(n):
    if n == 1 or n == 2:
        r = 1
    else:
        r = fibonacci(n - 1) + fibonacci(n - 2)
    return r

print(fibonacci(3))
"""
B(pys)

將引發 NameError。

$ py -3.8 testrecursivefun.py
Traceback (most recent call last):
  File "testrecursivefun.py", line 14, in <module>
    B(pys)
  File "testrecursivefun.py", line 2, in B
    exec(pys)
  File "<string>", line 9, in <module>
  File "<string>", line 6, in fibonacci
NameError: name 'fibonacci' is not defined

如果我直接在模塊下運行 exec(pys) ,異常就消失了。

原因已在另一個問題中描述過exec 如何與當地人合作? . 但我仍然不知道如何弄清楚exec()中的遞歸調用。 因為 function 名稱對我來說是動態的。 我不能將它添加到locals()exec() 誰能幫我弄清楚。

為了得到答案,您可以將代碼包裝在 function 中,因此遞歸 function 位於其本地 scope 中:

import textwrap

def B(pys):
    exec(pys, globals(), {})

pys="""
def fibonacci(n):
    if n == 1 or n == 2:
        r = 1
    else:
        r = fibonacci(n - 1) + fibonacci(n - 2)
    return r

print(fibonacci(11))
"""

def wrap(s):
    return "def foo():\n" \
           "{}\n" \
           "foo()".format(textwrap.indent(s, ' ' * 4))

B(wrap(pys))

通常,重新考慮使用 exec。

我實際上對你的問題很感興趣,所以我開始研究這個話題。 似乎解決您的問題的簡單方法是:

  1. 首先使用compile function in python 將字符串編譯為代碼
  2. 然后使用exec function 執行編譯后的代碼

這是示例解決方案:

psy="""
def fibonacci(n):
    if n == 1 or n == 2:
        r = 1
    else:
        r = fibonacci(n - 1) + fibonacci(n - 2)
    return r

print(fibonacci(3))
"""

def B(psy):
    code = compile(psy, '<string>', 'exec')
    exec(code, globals())

B(psy)

這里 compile 需要三個參數:

首先是字符串格式的代碼,其次是我們使用的文件名提示因為我們將字符串作為代碼本身,第三個可以是'exec'、'eval' 和 'single'之一。

鏈接包含有關如何在 python 中使用 exec 和 eval 的詳細說明。 請檢查它們以獲取詳細說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM