python - f2py: Exponiendo parámetros de módulos "usados"
numpy fortran90 (1)
He encontrado una solución temporal a este problema, pero no es óptima. Continuaré trabajando a través de la fuente f2py para poder entenderlo mejor y solucionar el problema dentro del propio código. Hasta entonces, esta es mi solución que se inspiró en el comentario de chatcannon sobre el tema que publiqué en el github de nympy .
Hay varias formas de abordar este problema desde un punto de vista temporal, incluidas algunas formas de modificar los archivos .pyf. No quiero tener que modificar los archivos .pyf, ya que se vuelve muy incómodo como parte de un paquete más grande. Para evitar esto, agregué directivas f2py a mi fuente f90.
Tomando el ejemplo de mi pregunta original:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
INTEGER, PARAMETER :: b = 2
END MODULE test2
simplemente agregue una directiva f2py en test2 para mostrar f2py cómo definir test2.a
:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
!f2py integer, parameter :: a ! THIS EXPOSES `a` in `test2`
INTEGER, PARAMETER :: b = 2
END MODULE test2
Importar desde el test.so
resultante, test.so
expone test2.a
correctamente:
In [1]: import test
In [2]: print test.test.a
1
In [3]: print test.test.b
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
.../test_solution/<ipython-input-3-798b14f59815> in <module>()
----> 1 print test.test.b
AttributeError: b
In [4]: print test.test2.a
1
In [5]: print test.test2.b
2
Supongo que esta pregunta se ha abordado en algún lugar, pero he pasado una cantidad excesiva de tiempo buscando la respuesta, incluida la búsqueda un poco del código fuente. He tratado de poner el problema en el primer párrafo. El resto muestra un ejemplo básico del problema.
Estoy intentando compilar un módulo que contiene una instrucción USE
que apunta a otro módulo más general. Preferiría mantener el módulo usado separado para que pueda usarse en varios "paquetes" como un conjunto de configuraciones generales. Cuando compilo los dos módulos usando f2py, todo funciona como se anuncia desde el lado de fortran, pero desde el lado de python, el USE
parece ignorarse. Si permito que f2py genere un archivo de firma, el archivo contiene una declaración USE
según corresponda, pero si completo la compilación e importo desde la biblioteca resultante, los parámetros del módulo usado no están disponibles en el módulo que contiene la declaración de uso. A continuación se presentan dos módulos que ilustran la situación:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
INTEGER, PARAMETER :: b = 2
END MODULE test2
Para mostrar el paso intermedio ejecuté f2py -h test.pyf test.f90 test2.f90
. Se genera el siguiente archivo de firma; tenga en cuenta que el módulo "test2" contiene "use test":
! -*- f90 -*-
! Note: the context of this file is case sensitive.
python module test ! in
interface ! in :test
module test ! in :test:test.f90
integer, parameter,optional :: a=1
end module test
module test2 ! in :test:test2.f90
use test
integer, parameter,optional :: b=2
end module test2
end interface
end python module test
! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/
Si ahora compilo con f2py --fcompiler=gfortran -c test.pyf test.f90 test2.f90
(igual que ejecutando f2py --fcompiler=gfortran -m test -c test.f90 test2.f90
sin crear el archivo de firma primero). Importar desde esta biblioteca en python expone test.test.a y test.test2.b, pero no expone test.test2.a como se puede ver aquí:
In [1]: import test
In [2]: print test.test.a
1
In [3]: print test.test2.b
2
In [4]: print test.test2.a
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/users/solbrig/svn_checkouts/inversion/satmet/branches/solbrig/rootpath/data/users
/GeoIPS/src/test/<ipython-input-4-bffcf464e408> in <module>()
----> 1 print test.test2.a
AttributeError: a
Para ilustrar que b
se define correctamente en test2 desde la perspectiva de fortran, el siguiente código usa test2 e imprime b
y b
:
SUBROUTINE run_test()
USE test2
IMPLICIT NONE
print *, "a = ", a
print *, "b = ", b
END SUBROUTINE run_test
Después de compilar con "f2py -m run_test -c test.f90 test2.f90 run_test.f90" y obtener run_test.so, run_test se puede importar en python y funciona como se espera:
In [1]: import run_test
In [2]: run_test.run_test()
a = 1
b = 2
Cualquier ayuda con este problema sería muy apreciada.