2009-05-15 5 views
2

Я пытаюсь написать небольшую функцию, которая получает имя переменной, проверяет, существует ли она, и если она не загружает ее из файла (с использованием pickle) в глобальное пространство имен.Загрузка файлов в переменные в python

Я попытался использовать это в файле:

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

Использования «глобал» имеет проблемы, что он работает только для текущий модуль. Вместо того, чтобы переходить «глобальные», лучше использовать «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) 

Будьте осторожны с именем модуля: основной скрипт всегда модуль главный. Если вы используете script.py и выполняете «скрипт импорта», вы получите отдельную копию своего кода, который обычно не тот, который вы хотите.

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')) 

 

EDIT: конечно, что только загружает глобал в глобал текущего модуля.

Если вы хотите загрузить материал в глобал другого модуля, который вы бы лучше, чтобы пройти в них в качестве параметра:

 

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()) 
 
+0

Это работает, только когда я загружаю файл с помощью execfile, но не когда загружаю его с импортом. Почему это? Благодаря! –

+0

Возможно, потому что глобальные переменные являются глобальными только для модуля, в котором они находятся. –

+0

Спасибо. Есть ли способ автоматически перейти от модуля к глобалям() переводчика? –