Python3: вставить рекурсивную функцию в exe c () в функции - PullRequest
2 голосов
/ 10 июля 2020

В python3, если функция с рекурсивным вызовом вводится в 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

Если я запустил exe c (pys) непосредственно под модулем, исключение исчезнет.

Причина описана в другом вопросе Как exe c работает с локальными? . Но я до сих пор не знаю, как мне понять рекурсивный вызов в exec(). Потому что имя функции для меня - Dynami c. Я не могу добавить его к locals() к exec(). Кто может помочь разобраться.

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Ради ответа вы можете обернуть свой код функцией, чтобы рекурсивная функция находилась в своей локальной области:

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))

Как правило, пересмотрите вариант использования exe c.

0 голосов
/ 10 июля 2020

Меня действительно заинтересовал ваш вопрос, поэтому я начал исследовать этот топи c. Похоже, простое решение вашей проблемы:

  1. Сначала скомпилируйте строку в код, используя функцию compile в 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)

Здесь компиляция принимает три параметра:

Сначала код в строковом формате, Во-вторых, это подсказка имени файла , которую мы использовали , поскольку мы принимаем строку как сам код, а третье может быть одним из 'exe c', 'eval' и ' single '.

Эта ссылка содержит подробное объяснение того, как вы должны использовать exe c и eval в python. Обязательно ознакомьтесь с ними для подробного объяснения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...