2016-10-10 2 views
2

У этого должен быть ответ, но я не могу его найти. Я использую довольно большой модуль python, называемый quippy. С помощью этого модуля можно определить межмолекулярный потенциал для использования в качестве калькулятора в ASE так:Как избежать повторного импорта модулей и переопределения большого объекта каждый раз при запуске скрипта

from quippy import * 
from ase import atoms 
pot=Potential("Potential xml_label=gap_h2o_2b_ccsdt_3b_ccsdt",param_filename="gp.xml") 
some_structure.set_calculator(pot) 

Это начало скрипта. Проблема в том, что import занимает около 3 секунд, а pot=Potential... занимает около 30 секунд со 100% -ной загрузкой процессора. (Я считаю, что это связано с разбором большого xml-файла ascii.) Если бы я набирал текст в интерактивном режиме, я мог бы сохранить модуль импортированным и определить потенциал, но при запуске скрипта он выполняется снова при каждом запуске.

Могу ли я сохранить модуль и потенциальный объект в памяти/диске между прогонами? Может ли поддерживать процесс python на холостом ходу и хранить эти вещи в памяти? Или запустите эти строки в интерпретаторе и как-нибудь вызовите остальную часть скрипта оттуда?

Любой подход - это хорошо, но нам нужна помощь!

+0

Как часто вы можете позвонить в скрипт? Если у вас достаточно ОЗУ, ваша ОС будет кэшировать файлы модулей, используемые во время 'import'. Если вы хотите сохранить 'pot', просто напишите его в файл, например. используя 'pickle'. – MisterMiyagi

ответ

0

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

import cPickle as pickle 
from quippy import Potential 
try: # try previously calculated value 
    with open('/tmp/pot_store.pkl') as store: 
     pot = pickle.load(store) 
except OSError: # fall back to calculating it from scratch 
    pot = quippy.Potential("Potential xml_label=gap_h2o_2b_ccsdt_3b_ccsdt",param_filename="gp.xml") 
    with open('/tmp/pot_store.pkl', 'w') as store: 
     pot = pickle.dump(pot, store) 

Существуют различные варианты оптимизации, например. проверяя, является ли ваш файл pickle старше файла, генерирующего его значение.

+0

Я собираюсь попробовать с этим кодом, но на самом деле я просто попытался с cPickle, и я не получил его на работу. Но что вы имеете в виду с сырыми файлами? Как мне кажется, сохранение его как двоичного кода было бы хитростью, но как? –

+0

Что вы подразумеваете под «не получилось»? Это часть стандартной библиотеки py2.7. Сырые файлы - это просто файлы, на которые вы пишете простые строки без какой-либо библиотеки сверху. Например, если 'pot' - это float, вы можете сделать' store.write (str (pot)) 'и' float (store.readline(). Strip()) '. – MisterMiyagi

+0

Я не был хорошо сформулирован. cPickle не выдавал ошибку, ни при загрузке, ни при загрузке, но при попытке запустить загруженный потенциал я получил ошибку. И, глядя на файл, это было несколько байтов, а не размер реального объекта. –

0

Я нашел одно решение, но меня интересуют альтернативы. Вы можете разделить сценарий на две части:

start.py:

from quippy import Potential 
from ase import atoms 
pot=Potential(... etc... 

body.py:

for i in range(max_int): 
     print "doing things" 
# etc... 

Затем введите интерпретатор питона и запустить стартап скрипт только один раз, но тело

[email protected]:~/dir$ python 
>>> execfile('start.py') 
>>> execfile('body.py') 
>>> #(change code of "body.py" in editor) 
>>> execfile('body.py') # again without reloading "start.py" 

Таким образом, это означает, что терминал занят, и сценарий затронут, но это wo RKS.

Смежные вопросы