简体   繁体   English

Python3:将递归 function 注入到 function 中的 exec() 中

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

In python3, if a function with recursive invoking is injected into exec() in a function, I got an error.在 python3 中,如果将带有递归调用的 function 注入到 function 中的exec()中,则会出现错误。 For example, below code例如,下面的代码

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)

will raise NameError.将引发 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

If I run exec(pys) directly under the module, the exception disappeared.如果我直接在模块下运行 exec(pys) ,异常就消失了。

The reason has been described in another question How does exec work with locals?原因已在另一个问题中描述过exec 如何与当地人合作? . . But I still don't know how I can figure out the recursive invoking in exec() .但我仍然不知道如何弄清楚exec()中的递归调用。 Because the function name is dynamic for me.因为 function 名称对我来说是动态的。 I cannot add it to locals() to exec() .我不能将它添加到locals()exec() Who can help me figure it out.谁能帮我弄清楚。

For the sake of an answer, you can wrap your code in a function so the recursive function is in its local scope:为了得到答案,您可以将代码包装在 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))

Generally, reconsider using exec.通常,重新考虑使用 exec。

I actually got interested in your question, so I started researching on this topic.我实际上对你的问题很感兴趣,所以我开始研究这个话题。 Seems like the simple solution to your problem is to:似乎解决您的问题的简单方法是:

  1. First compile the string to code using compile function in python首先使用compile function in python 将字符串编译为代码
  2. Then execute the compiled code using exec function然后使用exec function 执行编译后的代码

Here is the sample solution:这是示例解决方案:

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)

Here compile takes three parameters:这里 compile 需要三个参数:

First is the code in string format , Second is the filename hint which we used首先是字符串格式的代码,其次是我们使用的文件名提示as we take string as code itself, and third can be one of 'exec', 'eval' and 'single' .因为我们将字符串作为代码本身,第三个可以是'exec'、'eval' 和 'single'之一。

This link contains detail explanation of how you should use exec and eval in python.链接包含有关如何在 python 中使用 exec 和 eval 的详细说明。 Do check them out for detail explanation.请检查它们以获取详细说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM