-3

Assume that we have a string

function_string = 'def main():\n\treturn(1)'

How can this be compiled as a function during runtime and then be executed?

This is my current attempt, unfortunately it raises a NameError expressing that main is not defined:

self.run():
    exec(self.formatted_function_string) # similar to 'function_string' in the example
    print(main())
Eivind
  • 301
  • 6
  • 18
  • 1
    but, *why?* ... – DeepSpace Oct 20 '17 at 14:55
  • for using external text source as script(update!) – dsgdfg Oct 20 '17 at 14:55
  • 1
    @dsgdfg Then OP can execute that "external text source" on its own, or import it properly. No need to try and hack Python for that. – DeepSpace Oct 20 '17 at 14:59
  • 1
    Possible duplicate of [What is the best way to call a Python script from another Python script?](https://stackoverflow.com/questions/1186789/what-is-the-best-way-to-call-a-python-script-from-another-python-script) – Mel Oct 20 '17 at 15:00
  • @DeepSpace you're right but did you have any trick `update an exec without change exec`, i think he want use an `exec` as `python-shell` – dsgdfg Oct 20 '17 at 15:03
  • I assume that you are aware that `eval` and `exec` should generally be avoided because they can be a security risk. If not, please see [Eval really is dangerous](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) by SO veteran Ned Batchelder. – PM 2Ring Oct 20 '17 at 15:10
  • What about replacing `print(main())` by: `print(locals().get("main", lambda: None)())` ? – CristiFati Oct 20 '17 at 15:19
  • For some excellent info on exec and related topics, please see [What's the difference between eval, exec, and compile in Python?](https://stackoverflow.com/questions/2220699/whats-the-difference-between-eval-exec-and-compile-in-python) – PM 2Ring Oct 20 '17 at 16:34

1 Answers1

0

As I said in the comments, executing / evaluating arbitrary strings is a security risk. But if you really want to do this, you need to pass exec an appropriate globals dict. The natural choice here is to pass it the globals() dict, so that whatever names your exec defines get put into the global namespace.

def test(argstring):
    exec(argstring, globals())
    print(main())

function_string = 'def main():\n\treturn(1)'
test(function_string)
print(main)

typical output

1
<function main at 0xb7196cd4>
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182