当我通过程序中的选项(计算生物学实验)时,我通常会将它们传递给.py文件 所以我有这个.py文件,其内容如下:
starting_length=9
starting_cell_size=1000
LengthofExperiments=5000000
然后我执行文件并获取数据。由于程序全部在我的机器上,没有其他人可以访问它,所以它是安全的 我也可以很容易地写一个类似的文件:
def writeoptions(directory):
options=""
options+="starting_length=%s%s"%(starting_length,os.linesep)
options+="starting_cell_size=%s%s"%(starting_cell_size,os.linesep)
options+="LengthofExperiments=%s%s"%(LengthofExperiments,os.linesep)
...
open("%s%soptions.py"%(directory,os.sep),'w').write(options)
我想传递一个函数作为参数之一:
starting_length=9
starting_cell_size=1000
LengthofExperiments=5000000
def pippo(a,b):
return a+b
functionoperator=pippo
当然,在真正的实验中,函数pippo会复杂得多。不同于实验到实验。
但我无法做的是自动编写该功能。总之,如果其中一个选项是函数,我不知道如何推广writeoptions函数以继续编写选项。我当然可以复制原始文件,但这样做效率低,效率低(因为它包含许多未使用的额外选项),并且通常无法解决问题。
如何让python写下函数的代码,因为它写下变量的值?
答案 0 :(得分:13)
vinko@mithril$ more a.py def foo(a): print a vinko@mithril$ more b.py import a import inspect a.foo(89) print inspect.getsource(a.foo) vinko@mithril$ python b.py 89 def foo(a): print a
答案 1 :(得分:2)
您可能还会考虑其他一些数据持久性方法。在我自己的(天文学)研究中,我一直在试验两种不同的存储脚本以实现再现性的方法。第一种方法是将它们专门放在subversion存储库中,然后让作业提交脚本自动提交它们。例如,如果您只想在bash中执行此操作:
alias run_py='svn ci -m "Commit before running"; python2.5 $*'
并在脚本内部,为该文件输出前缀为current subversion revision number的输出,您将记录每个运行的脚本以及输入的内容。你可以根据需要将其从颠覆中拉回来。
跟踪函数输入的另一种功能基本上不那么全功能的方法可能是LodgeIt,一种接受XML-RPC输入并附带Python绑定的pastebin。 (它可以在本地安装,并且支持回复和更新现有的粘贴。)
但是,如果您正在寻找要包含的相对少量的代码,Vinko使用inspect的解决方案应该可以很好地工作。 Doug Hellman covered the inspect
module在他的Python Module of the Week系列中。您可以创建一个装饰器来检查每个选项和参数,然后根据需要将其打印出来(我将使用inspect.getargspec
来获取参数的名称。)
import inspect
from functools import wraps
def option_printer(func):
@wraps(func)
def run_func(*args, **kwargs):
for name, arg in zip(inspect.getargspec(func)[0], args) \
+ sorted(kwargs.items()):
if isinstance(arg, types.FunctionType):
print "Function argument '%s' named '%s':\n" % (name, func.func_name)
print inspect.getsource(func)
else:
print "%s: %s" % (name, arg)
return func(*args, **kwargs)
return run_func
这可能会更优雅,但在我的测试中,它适用于简单的参数和变量集。另外,lambdas可能会遇到一些麻烦。
答案 2 :(得分:0)
你在问这个吗?
def writeoptions(directory):
options=""
options+="starting_length=%s%s"%(starting_length,os.linesep)
options+="starting_cell_size=%s%s"%(starting_cell_size,os.linesep)
options+="LengthofExperiments=%s%s"%(LengthofExperiments,os.linesep)
options+="def pippo(a,b):%s" % ( os.linesep, )
options+=" '''Some version of pippo'''%s" % ( os.linesep, )
options+=" return 2*a+b%s" % ( os.linesep, )
open("%s%soptions.py"%(directory,os.sep),'w').write(options)
还是其他什么?
答案 3 :(得分:0)
虽然可以按照你的要求行事(如Vinko所示),但我会说分享代码更清晰。将pippo
和他的伙伴放在两个程序都可以访问的子模块中。
答案 4 :(得分:0)