3

I have a text file that contains Python function like this:

a.txt

def func():
    var = 5
    return var

And then I read this file in a Python script:

b.py

python_file = open("a.txt").read()

Now I want to assign the a.txt file's function to a variable without worrying about the function name and execute it. I tried something like this:

python_file = open("a.txt").read()
b = exec(python_file)
b()

But it didn't work, I tried execfile as well.

5
  • 1
    Why don't you just rename it to .py and import it in the normal way? Either way, note that exec doesn't return anything, read its documentation. Commented Aug 10, 2015 at 12:58
  • @jonrsharpe Sir It is .txt file. so cant import . and the requirement is such I don't know function name of txt file in python file. Commented Aug 10, 2015 at 13:01
  • ...a Python file is also just a text file, why not os.rename it? Commented Aug 10, 2015 at 13:02
  • 1
    I want to keep It txt file . In future the python function will come from database as string Commented Aug 10, 2015 at 13:05
  • 3
    Do you not think that kind of information would be useful in the question? Commented Aug 10, 2015 at 13:06

2 Answers 2

4

After you've executed the string, you can call func directly, as it has been added to your current namespace:

>>> exec("""def func():
    var = 5  # note that the semicolons are redundant and unpythonic
    return var""")
>>> func()
5

Per its documentation exec doesn't actually return anything, so there's no point assigning e.g. foo = exec(...).


To see what names are locally defined in the code being executed, pass an empty dictionary to exec as the locals parameter:

>>> ns = {}
>>> exec("""def func():
    var = 5
    return var""", globals(), ns)
>>> ns
{'func': <function func at 0x0315F540>}

You can then assign the function and call it as you normally would:

>>> b, = ns.values()  # this will only work if only one name was defined
>>> b()
5
Sign up to request clarification or add additional context in comments.

7 Comments

I don't want to call it by function name. I don't know the function name in python file. I wanna assign to a variable what ever function is there
@AshishNautiyal well that's probably going to be tough. What are you actually trying to achieve?
agreed Sir .But I want to find a way to assign it to a variable .
I have added how you can do that, but you still haven't really answered my questions.
@SDilmac how does that solve the problem? If you have a separate answer, please add it as an answer
|
2

Before offering my solution, I highly warn against do this unless you know for sure there is no malicious code in a.txt.

My solution uses the execfile function to load the text file and return the first object (could be a variable or function):

def load_function(filename):
    """ Assume that filename contains only 1 function """
    global_var = dict()
    execfile(filename, global_var)
    del global_var['__builtins__']
    return next(global_var.itervalues())

# Use it
myfunction = load_function('a.txt')
print myfunction()

Update

To be a little more careful, modify the return line like the following so that it skips variables (it cannot skip class declaration, however).

    return next(f for f in global_var.itervalues() if callable(f))

Update 2

Thank you johnsharpe for pointing out that there is no execfile in Python 3. Here is a modified solution which use exec instead. This time, the function should be found in the "local" scope.

def load_function(filename):
    """ Assume that filename contains only 1 function """
    with open(filename) as f:
        file_contents = f.read()
        global_var = dict()
        local_var = dict()
        exec file_contents in global_var, local_var
        return next(f for f in local_var.itervalues() if callable(f))

# Use it
myfunction = load_function('a.txt')
print myfunction()

2 Comments

Note that Python 3 doesn't have execfile, see e.g. docs.python.org/3/whatsnew/3.0.html#builtins, stackoverflow.com/q/436198/3001761
My bad. I don't have Python 3. In that case, your solution (open text file, read contents, call exec) combine with mine (get the first callable from the global name space) will work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.