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.

16
demandé sur Vorticity 2013-06-18 00:20:28

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
6
répondu Vorticity 2013-09-26 07:59:54