简体   繁体   English

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

[英]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. 如果我有一个包含python函数定义的文本文件,我如何从另一个Python程序调用函数。 Ps: The function will be defined in the Python program that does the call. Ps:该函数将在执行调用的Python程序中定义。

Ways in which can be done: 可以做的方式:

  1. Consider the python function as a module and call it. 将python函数视为一个模块并调用它。 Constraint here is that I have to convert a python bare function into a module which would give errors. 这里的约束是我必须将python bare函数转换为一个会产生错误的模块。

  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"). 另一个疑问是,如果这个人(显然不是我)写了一个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. Edit2:由于很多人要求我使用exec,我想指出这个线程 ,尤其是命名空间问题。 It gives user a lot of chances to "circumvent" python. 它为用户提供了很多“绕过”python的机会。 Don't y'all think? 你们都不觉得?

You are looking for the exec keyword. 您正在寻找exec关键字。

>>> 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: 的test.txt:

def a():
    print "a()"

test.py: 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 链接到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: compile()和eval()可以做到这一点:

>>> 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? 像Java中的反射一样? If so, Python has a module named imp to provide it. 如果是这样,Python有一个名为imp的模块来提供它。

foo.py 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: 上面的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)]

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: 在这里查看: 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'

You can use execfile: 你可以使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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