diemacht
diemacht

Reputation: 2102

How to run "exec" from the global scope in python

I have a Class. In that class I have a function. In the function, I have a string variable that holds definitions of several python functions.

I would like from the function to create the functions that are defined in the variable, such that they will be created in the global scope.

After this operation, I would like to be able to call to the new function from the global scope.

For example:

class MyClass:
  def create_functions():
   functions_to_create = """
def glob1():
  return "G1"

def glob2():
  return "G2"
"""
   # ----> HERE IS THE MISSING PART, LIKE RUNNING exec in the global scope <----


# The following function should work:
def other_function_in_global_scope():
  print "glob1: %s, glob2: %s" % (glob1(), glob2())

What should be in the MISSING PART?

Thanks in advance!!!

Upvotes: 2

Views: 2268

Answers (2)

Jan Hudec
Jan Hudec

Reputation: 76376

In python the overrides can monkey-patch anything anytime, but if you just evaluate a bit of code in global namespace, the risk of inadvertent symbol conflict. I'd suggest instead the customer would provide a module and your code would call functions in it if they were defined there (and default implementations otherwise).

That said, documentation suggests:

exec(functions_to_create, globals())

Upvotes: 4

Zimm3r
Zimm3r

Reputation: 3425

Several things first. What is your reason to creating a function to create other functions? What are you trying to do? There might be a better way. Also here is another way to so called create function that doesn't involve playing around with exec.

>>> def create_functions():
...     global glob1
...     def glob1():
...             return "G1"
... 
>>> glob1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'glob1' is not defined
>>> create_functions()
>>> glob1()
'G1'
>>> 

Edit


Injecting source code without exec (THIS IS NOT A GOOD IDEA AT ALL)

Have you customer submit their code then just do a custom import

  1. Customer Submit Code
  2. Save that code as say custom.py
  3. In your code that you want to let the customer inject into do something like the following

    import os if os.path.exists("custom.py"): import custom custom.inject()

That way they can give you their code you call inject and they can change things.

Upvotes: 2

Related Questions