我有一个助手脚本,我想从充当服务器的主脚本中调用它。该主脚本如下所示:
Class Stuff():
def __init__(self, f):
self.f = f
self.log = {}
def execute(self, filename):
execfile(filename)
if __name__ == '__main__':
#start this script as server
clazz = Stuff()
#here helper_script name will be provided by client at runtime
clazz.execute(helper_script)
现在,客户端将通过将其名称提供给主脚本(服务器)来调用此帮助脚本。执行后,我想在主脚本中保留辅助脚本的变量(即:a,b)。我知道一种方法是将这些变量从帮助程序脚本返回到主脚本。但是还有其他方法可以保留帮助程序脚本的所有变量。这是辅助脚本的样子:
import os
a = 3
b = 4
我尝试使用execfile和子进程。
答案 0 :(得分:7)
您可以将本地字典发送到execfile
。执行完文件后,该词典将包含它定义的局部变量。
class Stuff():
def __init__(self):
self.log = {}
def execute(self, filename):
client_locals = {}
execfile(filename, globals(), client_locals)
return client_locals
if __name__ == '__main__':
#start this script as server
clazz = Stuff()
#here helper_script name will be provided by client at runtime
client_locals = clazz.execute('client.py')
print client_locals
使用您的client.py
,将打印:
{'a': 3, 'b': 4, 'os': <module 'os' from '/Users/.../.pyenv/versions/2.7.6/lib/python2.7/os.pyc'>}
对execfile
的警告:请勿将其用于不受信任来源的文件。
答案 1 :(得分:0)
如评论中所述,您应该return
来自帮助程序脚本的值。如果不止一个,请将其粘贴在列表或字典中(namedtuple
很方便)。
关键是您需要将execfile
的结果分配给服务器脚本中的变量。不必做任何大的事情,它可以直接转储到列表之类的集合中。
class Stuff():
def __init__(self, f):
self.f = f
self.log = {}
self.storage = []
def execute(self, filename):
self.storage.append(execfile(filename))
if __name__ == '__main__':
#start this script as server
clazz = Stuff()
#here helper_script name will be provided by client at runtime
clazz.execute(helper_script)
a = 3
b = 4
return (a, b)
另一种方法是让帮助文件打印结果,但重定向stdout
。如果您使用的是subprocess
,那么这很简单,documentation中对此进行了详细说明(如果有帮助,我可以添加一个示例)。与exec / execfile
相比,我对subprocess
方法不太熟悉,但是对this SO question有一个解释。
如果其他SO问题发生任何事情,请复制以下两个示例的代码:
code = """
i = [0,1,2]
for j in i :
print j
"""
from cStringIO import StringIO
old_stdout = sys.stdout
redirected_output = sys.stdout = StringIO()
exec(code)
sys.stdout = old_stdout
print redirected_output.getvalue()
import sys
import StringIO
import contextlib
@contextlib.contextmanager
def stdoutIO(stdout=None):
old = sys.stdout
if stdout is None:
stdout = StringIO.StringIO()
sys.stdout = stdout
yield stdout
sys.stdout = old
code = """
i = [0,1,2]
for j in i :
print j
"""
with stdoutIO() as s:
exec code
print "out:", s.getvalue()
答案 2 :(得分:0)
@Daniel Hepper感谢您的简洁说明。对于Python3.x,不支持execfile。您可以参考https://stackoverflow.com/a/437857/1790603
答案 3 :(得分:0)
您可以使用locals()
方法访问在任何给定名称空间中定义的所有符号(变量,类,方法...)。这是一个例子
import os
a = 1
b = 2
return locals()
将产生包含(包括一些技术性内容)的字典
{'os': <module 'os' from '...'>, 'a': 1, 'b': 2}
因此,如果将以上内容保存在名为foo.py
的文件中,则可以使用以下值:
foo_vals = execfile(`foo.py`)
print(foo_vals["a"])
> 1
但这不是我要使用的方法。根据您脚本中代码的数量,该词典巨大,并且杂乱了您不需要的内容,而我只会将其用于调试目的。以下是其他选项,按“良好的编码习惯”排序:
import foo
,然后使用a
,b
访问foo.a
和foo.b
。 (尽管我认为它只能执行一次,但是您可以在代码内的任何地方调用import foo
。execfile