Как я могу создать и выполнить функцию / метод во время работы скрипта?

Часть скрипта, которую я делаю, требует, чтобы новые функции были определены и доступны во время выполнения. Функция определяет ОК, но я получаю ошибку, когда пытаюсь ее использовать:

(import io)

(defn exec-code [str]
      (eval (apply read [] {"from_file" (.StringIO io str)})))

(setv ectest "(print \"Code execution function works!\")")
(exec-code ectest)

(setv testfunc [])
(.append testfunc "(defn -testfunc- [] (print \"Self-execution works!\"))")
(.append testfunc "(-testfunc-)")
(for [line testfunc] (print line) (exec-code line))

Результаты в:

Code execution function works!
(defn -testfunc- [] (print "Self-execution works!"))
(-testfunc-)
Traceback (most recent call last):
  File "/usr/bin/hy", line 9, in <module>
    load_entry_point('hy==0.11.0', 'console_scripts', 'hy')()
  File "/usr/lib/python3/dist-packages/hy/cmdline.py", line 347, in hy_main
    sys.exit(cmdline_handler("hy", sys.argv))
  File "/usr/lib/python3/dist-packages/hy/cmdline.py", line 335, in cmdline_handler
    return run_file(options.args[0])
  File "/usr/lib/python3/dist-packages/hy/cmdline.py", line 210, in run_file
    import_file_to_module("__main__", filename)
  File "/usr/lib/python3/dist-packages/hy/importer.py", line 78, in import_file_to_module
    eval(ast_compile(_ast, fpath, "exec"), mod.__dict__)
  File "code-trace.hy", line 41, in <module>
    (for [line testfunc] (print line) (exec-code line))
  File "code-trace.hy", line 33, in exec_code
    (eval (apply read [] {"from_file" (.StringIO io str)})))
  File "/usr/lib/python3/dist-packages/hy/importer.py", line 126, in hy_eval
    return eval(ast_compile(expr, "<eval>", "eval"), namespace)
  File "<eval>", line 1, in <module>
NameError: name '_testfunc_' is not defined

1 ответ

Это похоже на проблему пространства имен. Я думаю, что eval работает в изолированном пространстве имен, поэтому второй вызов ничего не знает о первом.

Попробуй это:

(defn exec-code [str]
  (eval (apply read [] {"from_file" (.StringIO io str)}) (globals)))

Который определяет пространство имен для глобальных. Это выводит:

Code execution function works!
(defn -testfunc- [] (print "Self-execution works!"))
(-testfunc-)
Self-execution works!

для меня.

Другие вопросы по тегам