简体   繁体   中英

How to call a function stored in another file from a Python program?

If I have a text file that contains a python function definition, how can I make the function call from another Python program. Ps: The function will be defined in the Python program that does the call.

Ways in which can be done:

  1. Consider the python function as a module and call it. Constraint here is that I have to convert a python bare function into a module which would give errors.

  2. Insert the code(function code) into the program that calls the function.

Which would be the better way to go about it?

Edit: Thank you for all the replies. Have shed a lot of light on the initial confusion I myself had. Another doubt would be, what if the person(Obviously, not me) has written a os.system("rm -rf"). And I end up executing it. That would mean doomsday for me, right?

Edit2: As a lot of you have asked me to use exec, I would like to point to the this thread and most particularly the namespace problem. It gives user a lot of chances to "circumvent" python. Don't y'all think?

You are looking for the exec keyword.

>>> mycode = 'print "hello world"'
>>> exec mycode
Hello world

So if you read your text file as text (assuming that it only contains the function) like:

test.txt:

def a():
    print "a()"

test.py:

mycode = open('test.txt').read()
exec mycode # this will execute the code in your textfile, thus define the a() function
a() # now you can call the function from your python file

Link to doc: http://docs.python.org/reference/simple_stmts.html#grammar-token-exec%5Fstmt

You may want to look at the compile statement too: here .

compile() and eval() can do the trick:

>>> code = compile('def foo(a): return a*2', '<string>', 'exec')
>>> eval(code)
>>> foo
52: <function foo at 0x01F65F70>
>>> foo(12)
53: 24

or with file:

with open(filename) as source:
    eval(compile(source.read(), filename, 'exec'))

A way like Reflection in Java? If so, Python has a module named imp to provide it.

foo.py

def foo():
  return "return from function foo in file foo.py"

some code anywhere

modes = imp.get_suffixes() #got modes Explained in link below
mode = modes[-2] # because I want load a py file
with open("foo.py") as file:
  m = imp.load_module("name", file, "foo.py", mode)
print(m.foo())

above mode = modes[-2] because my imp.get_suffixes() is:

>>> imp.get_suffixes()
[('.cpython-32m.so', 'rb', 3), ('module.cpython-32m.so', 'rb', 3), ('.abi3.so', 'rb', 3), ('module.abi3.so', 'rb', 3), ('.so', 'rb', 3), ('module.so', 'rb', 3), ('.py', 'U', 1), ('.pyc', 'rb', 2)]

here is my output:

Python 3.2.1 (default, Aug 11 2011, 01:27:29) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import imp
>>> with open("foo.py") as file:
...   m = imp.load_module("foo", file, "foo.py", ('.py', 'U', 1))
... 
>>> m.foo()
'return from function foo in file foo.py'

Check it here: http://docs.python.org/py3k/library/imp.html Both python 2.7 and python 3 works:

Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import imp
>>> imp.get_suffixes()
[('.so', 'rb', 3), ('module.so', 'rb', 3), ('.py', 'U', 1), ('.pyc', 'rb', 2)]
>>> with open("foo.py") as file:
...   m = imp.load_module("foo", file, "foo.py", ('.py', 'U', 1))
... 
>>> m.foo()
'return from function foo in file foo.py'

You can use execfile:

execfile("path/example.py")

# example.py
# def example_func():
#     return "Test"
#

print example_func()
# >Test

EDIT:

In case you want to execute some unsecure code, you can try to sandbox it this way, although it is probably not very safe anyway:

def execfile_sandbox(filename):
    from copy import copy
    loc = globals()
    bi  = loc["__builtins__"]
    if not isinstance(bi, dict): bi = bi.__dict__ 

    bi = copy(bi)        
    # no files
    del bi["file"]    
    # and definitely, no import
    del bi["__import__"]
    # you can delete other builtin functions you want to deny access to

    new_locals = dict()
    new_locals["__builtins__"] = bi
    execfile(filename, new_locals, new_locals)

Usage:

try:
    execfile_sandbox("path/example.py")
except:
    # handle exception and errors here (like import error)
    pass

I am not sure what is your purpose, but I suppose that you have function in one program and you do want that function run in another program. You can "marshal" function from first to second.

Example, first program:

# first program
def your_func():
    return "your function"

import marshal
marshal.dump(your_func.func_code, file("path/function.bin","w"))

Second program:

# Second program

import marshal, types
code = marshal.load(file("path/function.bin"))
your_func = types.FunctionType(code, globals(), "your_func")

print your_func()
# >your function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM