F2py: exposer les paramètres des modules "utilisés"
je suppose que cette question a été abordée quelque part, mais j'ai passé un temps démesuré à chercher la réponse, y compris à creuser un peu dans le code source. J'ai essayé de mettre le problème dans le premier paragraphe. Le reste montre un exemple de base du problème.
j'essaie de compiler un module qui contient un USE
énoncé pointant vers un autre module plus général. Je préférerais garder le module utilisé séparé pour qu'il puisse être utilisé dans plusieurs "paquets" comme un ensemble de paramètres généraux. Quand je compile les deux modules en utilisant f2py, tout fonctionne comme annoncé du côté fortran, mais du côté python USE
semble être ignorée. Si j'autorise f2py à générer un fichier de signature, le fichier contient un USE
déclaration comme c'est le cas, mais si je complète la compilation et l'importation de la bibliothèque les paramètres du module ne sont pas disponibles dans le module qui contient la déclaration d'utilisation. Dessous deux modules illustrent la situation:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
INTEGER, PARAMETER :: b = 2
END MODULE test2
afin de montrer l'intermédiaire de l'étape, j'ai couru f2py -h test.pyf test.f90 test2.f90
. Le fichier de signature suivant est généré; notez que le module "test2" contient "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 je compile maintenant avec f2py --fcompiler=gfortran -c test.pyf test.f90 test2.f90
j'obtiens le test.so (same as running f2py --fcompiler=gfortran -m test -c test.f90 test2.f90
sans créer d'abord le fichier de signature). Importer de cette bibliothèque en python expose le test.test.un et de test.test2.b, mais n'expose pas le test.test2.une comme on peut le voir ici:
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
juste pour illustrer cela b
est correctement défini dans test2 du point de vue de fortran, le code suivant utilise test2 et imprime à la fois b
et b
:
SUBROUTINE run_test()
USE test2
IMPLICIT NONE
print *, "a = ", a
print *, "b = ", b
END SUBROUTINE run_test
après compilation avec " f2py-m run_test-C test.F90 test2.F90 run_test.f90" et obtenir run_test.ainsi, run_test peut être importé en python et fonctionne comme prévu:
In [1]: import run_test
In [2]: run_test.run_test()
a = 1
b = 2
toute aide dans ce domaine serait grandement appréciée.
TL;DR: lorsqu'un module F90 qui contient un USE
est compilé par f2py il n'expose pas les paramètres définis dans le module "utilisé" comme attributs en Python.
1 réponses
j'ai trouvé une solution temporaire à ce problème, mais il n'est pas optimale. Je vais continuer à travailler à travers la source f2py pour que je puisse mieux la comprendre et résoudre le problème dans le code lui-même. Jusque là, c'est ma solution qui s'est inspirée de le commentaire de chatcannon à la question que j'ai posté à GitHub de nympy.
il y a plusieurs façons d'aborder ce problème d'un point de vue temporaire, y compris un couple de façons de modifier le .fichiers pyf. Je ne voulez pas avoir à modifier la .fichiers pyf car il devient très encombrant dans le cadre d'un paquet plus grand. Pour éviter cela, j'ai ajouté des directives f2py à ma source f90.
en prenant l'exemple de ma question originale:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
INTEGER, PARAMETER :: b = 2
END MODULE test2
il suffit d'ajouter une directive f2py dans test2 pour montrer à f2py comment définir 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
Importer à partir de la résultante test.so
correctement expose test2.a
:
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