将文件加载到变量中
我正在尝试写一个小函数,这个函数可以获取一个变量名,检查这个变量是否存在,如果不存在,就从一个文件里加载它(使用pickle),并把它放到全局命名空间里。
我在一个文件里试过这样写:
import cPickle
#
# Load if neccesary
#
def loadfile(variable, filename):
if variable not in globals():
cmd = "%s = cPickle.load(file('%s','r'))" % (variable, filename)
print cmd
exec(cmd) in globals()
但是它不管用——变量没有被定义。我哪里出错了呢?
2 个回答
2
你可以完全不使用exec这个功能:
import cPickle
#
# Load if neccesary
#
def loadfile(variable, filename):
g=globals()
if variable not in g:
g[variable]=cPickle.load(file(filename,'r'))
补充说明:当然,这样做只是把全局变量加载到当前模块的全局变量中。
如果你想把东西加载到另一个模块的全局变量中,最好是把它们作为参数传进去:
import cPickle
#
# Load if neccesary
#
def loadfile(variable, filename, g=None):
if g is None:
g=globals()
if variable not in g:
g[variable]=cPickle.load(file(filename,'r'))
# then in another module do this
loadfile('myvar','myfilename',globals())
2
使用'globals'有个问题,就是它只在当前模块有效。与其到处传递'globals',不如直接在一个命名空间上使用内置的'setattr'。这样的话,你就可以在实例和模块上重复使用这个函数。
import cPickle
#
# Load if neccesary
#
def loadfile(variable, filename, namespace=None):
if module is None:
import __main__ as namespace
setattr(namespace, variable, cPickle.load(file(filename,'r')))
# From the main script just do:
loadfile('myvar','myfilename')
# To set the variable in module 'mymodule':
import mymodule
...
loadfile('myvar', 'myfilename', mymodule)
要注意模块的名字:主脚本总是一个名为main的模块。如果你运行script.py并执行'import script',你会得到一份代码的单独副本,这通常不是你想要的结果。