2016-10-26 4 views
1

Я пытаюсь получить доступ к некоторым подпрограммам Fortran с использованием F2PY, но во время последовательных вызовов от IPython я столкнулся со следующей проблемой. Возьмите этот минимальный Fortran кода (надеюсь, что я ничего не закодировать глуп, мой Fortran немного ржавый ..):Обновить импорт в IPython

! test.f90 
module mod 
    integer i 
contains 
    subroutine foo 
    i = i+1 
    print*,i 
    end subroutine foo 
end module mod 

Если я компилирую это с помощью F2PY (f2py3.5 -c -m test test.f90), импортировать его в Python и назвать его дважды:

# run.py 
import test 
test.mod.foo() 
test.mod.foo() 

Полученный результат:

$ python run.py 
      1 
      2 

Так на каждом вызове foo(), i увеличивается, что должно произойти. Но между различными вызовами run.py (либо из командной строки, либо с помощью интерпретатора IPython) все должно быть «перезагружено», то есть печатный счетчик должен начинаться с 1 для каждого вызова. Это происходит при вызове run.py из командной строки, но если я вызвать скрипт несколько раз из IPython, i продолжает расти:

In [1]: run run.py 
      1 
      2 

In [2]: run run.py 
      3 
      4 

Я знаю, что есть много сообщений, показывающие, как перезарядить импорт (с использованием autoreload в IPython , importlib.reload(), ...), но ни один из них, похоже, не работает для этого примера. Есть ли способ принудительно перезагрузить/импортировать?

Некоторые примечания сторон: (1) Код Fortran, который я пытаюсь получить, довольно большой, старый и грязный, поэтому я бы предпочел ничего не менять; (2) Я мог легко сделать test.mod.i = something между вызовами, но реальный код Fortran слишком сложен для таких решений; (3) Я бы предпочел решение, которое я могу добавить в код Python, например. настройки (autoreload, ..), которые я должен вручную поместить в интерпретатор IPython (забудьте об этом один раз и ...)

+0

Похоже, тест сценария .py импортирует себя. Как выглядит код Python, созданный из test.f90? – martineau

+0

Извините, плохо выбранное имя для 'test.py', я переименовал его (что дает тот же результат). Какой код Python сгенерировал? 'F2PY' дает мне только общую/динамическую библиотеку (или то, что она называется, файлы' .so'), которые я импортирую в своем сценарии на Python – Bart

+0

Извините, моя ошибка (я не очень хорошо знаком с ' F2PY'). Что вы подразумеваете под «между разными вызовами« run.py' »- как это _called_? – martineau

ответ

0

Если вы можете немного изменить код fortran, вы можете сбросить его без повторного импорта (возможно, быстрее).
Изменение касается введения i в качестве общего и сброса его извне. Измененная Фортран код будет выглядеть этот

 ! test.f90 
     module mod 
     common /set1/ i 
     contains 
     subroutine foo 
     common /set1/ i 
     i = i+1 
     print*,i 
     end subroutine foo 
     end module mod 

сброса переменной i из питона, как показано ниже:

import test 
test.mod.foo() 
test.mod.foo() 
test.set1.i = 0 #reset here 
test.mod.foo() 

Это должно произвести результат следующим образом:

python run.py 
     1 
     2 
     1