如何从Python程序中调用存储在另一个文件中的函数?

时间:2011-10-04 07:42:03

标签: python

如果我有一个包含python函数定义的文本文件,我该如何从另一个Python程序调用函数。 Ps:该函数将在执行调用的Python程序中定义。

可以做的事情:

  1. 将python函数视为模块并调用它。这里的约束是我必须将python bare函数转换为一个会产生错误的模块。

  2. 将代码(功能代码)插入调用该函数的程序中。

  3. 哪种方式更好?

    编辑:感谢您的回复。对我自己最初的困惑已经有很多了解。另一个疑问是,如果这个人(显然不是我)写了一个os.system(“rm -rf”)会怎么样。我最终执行它。那对我来说意味着世界末日,对吗?

    Edit2:由于很多人要求我使用exec,我想指出这个thread,尤其是命名空间问题。它为用户提供了很多“绕过”python的机会。你们都不觉得吗?

5 个答案:

答案 0 :(得分:5)

您正在寻找 exec 关键字。

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

因此,如果您将文本文件作为文本读取(假设它只包含该函数),例如:

的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

链接到doc:http://docs.python.org/reference/simple_stmts.html#grammar-token-exec%5Fstmt

您也可以查看编译语句:here

答案 1 :(得分:2)

compile()和eval()可以做到这一点:

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

或文件:

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

答案 2 :(得分:2)

像Java中的反射一样?如果是这样,Python有一个名为imp的模块来提供它。

foo.py

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

任何地方的代码

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())

以上mode = modes[-2],因为我的imp.get_suffixes()是:

>>> 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)]

这是我的输出:

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'

在此处查看:http://docs.python.org/py3k/library/imp.html python 2.7和python 3都可以工作:

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'

答案 3 :(得分:1)

您可以使用execfile:

execfile("path/example.py")

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

print example_func()
# >Test

修改

如果您想执行某些不安全的代码,可以尝试以这种方式对其进行沙盒化, 虽然它可能不太安全:

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)

用法:

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

答案 4 :(得分:0)

我不确定你的目的是什么,但我想你在一个程序中有功能而你确实希望该功能在另一个程序中运行。你可以从第一个到第二个“编组”功能。

示例,第一个程序:

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

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

第二个程序:

# 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