Загрузка файлов в переменные в Python - PullRequest
2 голосов
/ 15 мая 2009

Я пытаюсь написать небольшую функцию, которая получает имя переменной, проверяет, существует ли она и, если нет, загружает ее из файла (используя 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 голосов
/ 15 мая 2009

При использовании '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', вы получите отдельную копию своего кода, которая обычно не соответствует вашим ожиданиям.

2 голосов
/ 15 мая 2009

Вы можете полностью избежать 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())

...