Comment utilisez-vous Fortran 90 données du module
-
11-09-2019 - |
Question
Disons que vous avez un module Fortran 90 contenant des lots des variables, des fonctions et des sous-routines. Dans votre déclaration USE
, quelle convention suivez-vous:
- déclarer explicitement que vous êtes variables / fonctions / sous-routines en utilisant la syntaxe de
, only :
, tels queUSE [module_name], only : variable1, variable2, ...
? - Insérer une
USE [module_name]
générale?
D'une part, la clause de only
rend le code un peu plus bavard. Cependant, il vous oblige à vous répéter dans le code et si votre module contient beaucoup des variables / fonctions / sous-routines, les choses commencent à regarder indisciplinés.
Voici un exemple:
module constants
implicit none
real, parameter :: PI=3.14
real, parameter :: E=2.71828183
integer, parameter :: answer=42
real, parameter :: earthRadiusMeters=6.38e6
end module constants
program test
! Option #1: blanket "use constants"
! use constants
! Option #2: Specify EACH variable you wish to use.
use constants, only : PI,E,answer,earthRadiusMeters
implicit none
write(6,*) "Hello world. Here are some constants:"
write(6,*) PI, &
E, &
answer, &
earthRadiusInMeters
end program test
Mise à jour Espérons que quelqu'un dit quelque chose comme "Fortran? Juste recoder en C #!" si je peux vous voter vers le bas.
Mise à jour
J'aime réponse de Tim Whitcomb , qui compare la USE modulename
de Fortran avec from modulename import *
Python. Un sujet qui a été sur le débordement de pile avant:
-
'import module' ou 'd'importation du module'
- Dans une réponse, Mark Roddy mentionné:
Ne pas utiliser 'du module import *'. Pour tout ensemble de code grand raisonnable, si vous 'importation * votre sera probablement cimentation dans le module, incapable à supprimer. En effet, il est difficile de déterminer quels éléments utilisés dans le code sont en provenance de « module », ce qui rend l'est pour arriver au point où vous pensez que vous n'utilisez pas importer plus, mais sa très difficile d'être sûr.
- Dans une réponse, Mark Roddy mentionné:
-
Quelles sont les bonnes règles de base pour python les importations
- réponse DBR contient
ne fait pas de x * importation - il fait votre code très difficile à comprendre, comme vous ne pouvez pas voir facilement où une méthode Provenant de (x de l'importation *, de y import *; my_func () - où est my_func défini?)
- réponse DBR contient
Alors, je me penche vers un consensus indiquant explicitement tous les éléments que je utilise dans un module via
USE modulename, only : var1, var2, ...
Et comme Stefano Borini mentionne ,
[si] vous avez un module si grand que vous se sentir obligé d'ajouter seulement, cela signifie que votre module est trop grand. Diviser.
La solution
Il est une question d'équilibre.
Si vous utilisez seulement quelques trucs du module, il est logique si vous ajoutez seulement, pour indiquer clairement ce que vous utilisez.
Si vous utilisez beaucoup de choses à partir du module, sera spécifier que le suivi par beaucoup de choses, donc il a moins de sens. Vous êtes essentiellement picorage ce que vous utilisez, mais le vrai fait est que vous êtes dépendant de ce module dans son ensemble.
Cependant, à la fin de la meilleure philosophie est celle-ci: si vous êtes préoccupés par la pollution de l'espace de noms, et vous avez un module si grand que vous vous sentez obligé d'ajouter seulement, cela signifie que votre module est trop grand. Diviser.
Mise à jour: Fortran? juste recoder en python;)
Autres conseils
Je l'habitude de le faire use modulename
- alors que ma demande a grandi, je l'ai trouvé de plus en plus difficile de trouver la source de fonctions (sans se tourner vers grep) - une partie de l'autre code flottant autour du bureau utilise encore un -subroutine-par-fichier, qui a son propre ensemble de problèmes, mais il rend beaucoup plus facile d'utiliser un éditeur de texte pour se déplacer à travers le code et le suivi rapidement ce que vous avez besoin.
Après avoir connu, je suis devenu un converti à l'aide use
... only
chaque fois que possible. J'ai aussi commencé à ramasser Python, et la voir de la même manière que from modulename import *
. Il y a beaucoup de grandes choses que les modules vous donnent, mais je préfère garder mon espace de nom global bien contrôlé.
Ne pas répondre exactement à la question ici, juste jeter dans une autre solution que j'ai trouvé utile dans certaines circonstances, si pour une raison quelconque, vous ne voulez pas partager votre module et commencer à obtenir des affrontements d'espaces de noms. Vous pouvez utiliser les types dérivés pour stocker plusieurs espaces de noms dans un module.
S'il y a un regroupement logique des variables, vous pouvez créer votre propre type dérivé pour chaque groupe, stocker une instance de ce type dans le module et vous pouvez importer tout le groupe que vous arrive d'avoir besoin.
Petit exemple: Nous avons beaucoup de données dont certaines sont entrées utilisateur et d'autres qui est le résultat d'initialisations divers
.module basicdata
implicit none
! First the data types...
type input_data
integer :: a, b
end type input_data
type init_data
integer :: b, c
end type init_data
! ... then declare the data
type(input_data) :: input
type(init_data) :: init
end module basicdata
Maintenant, si un sous-programme utilise uniquement les données de init
, vous importez juste que:
subroutine doesstuff
use basicdata, only : init
...
q = init%b
end subroutine doesstuff
Ceci est certainement pas une solution universelle, vous obtenez une verbosité supplémentaire de la syntaxe de type dérivé et il sera bien sûr aider à peine si votre module est pas le basicdata
genre ci-dessus, mais plus d'un allthestuffivebeenmeaningtosortout
variety. Quoi qu'il en soit, j'ai eu un peu de chance à obtenir un code qui correspond à plus facile dans le cerveau de cette façon.
L'avantage principal d'utilisation, seulement pour moi est qu'il évite de polluer mon espace de noms global avec des trucs que je ne ai pas besoin.
D'accord avec la plupart des réponses déjà données, use ..., only: ...
est la voie à suivre, les types d'utilisation quand il est logique, appliquez python penser autant que possible. Une autre suggestion est d'utiliser les conventions de nommage appropriées dans votre module importé, ainsi que les déclarations private
/ de public
.
Par exemple, la bibliothèque netcdf
utilise nf90_<some name>
, ce qui limite la pollution de l'espace sur le côté importateur.
use netcdf ! imported names are prefixed with "nf90_"
nf90_open(...)
nf90_create(...)
nf90_get_var(...)
nf90_close(...)
De même, l'emballage ncio à cette bibliothèque utilise nc_<some name>
(nc_read
, nc_write
...) .
Il est important, avec de telles conceptions où use: ..., only: ...
est faite moins pertinente, vous feriez mieux de contrôler l'espace de noms du module importé en définissant les attributs appropriés private
/ public
dans l'en-tête, de sorte qu'un rapide coup d'oeil à ce sera suffisant pour les lecteurs de évaluer quel niveau de « pollution », ils sont confrontés. Ceci est essentiellement le même que use ..., only: ...
, mais du côté du module importé -. Ainsi à écrire qu'une seule fois, et non à chaque importation)
Une autre chose: dans la mesure où l'orientation objet et python sont concernés, une différence à mon avis est que Fortran ne favorise pas vraiment les procédures liées par type, en partie parce qu'il est une norme relativement nouvelle (par exemple pas compatible avec nombre d'outils, et moins rationnelle, il est juste inhabituel) et parce qu'il casse le comportement pratique comme la copie de type dérivé sans procédure (type(mytype) :: t1, t2
et t2 = t1
). Cela signifie que vous avez souvent importer le type et toutes les procédures associée à un type serait-être, au lieu de simplement la classe. Ce seul fait Fortran plus bavard par rapport à python, et des solutions pratiques comme une convention de nommage préfixe peut être utile.
OMI, la ligne de fond est: choisissez votre style de codage pour les personnes qui le liront (ce qui inclut votre auto plus tard), comme enseigné par python. Le meilleur est le use ..., only: ...
plus bavard à chaque importation, mais dans certains cas, une simple convention de nommage fera (si vous êtes assez disciplinés ...).
Oui, s'il vous plaît utiliser use module, only: ...
. Pour les grandes bases de code avec les programmeurs multiples, il rend le code plus facile à suivre par tous (ou tout simplement utiliser grep
).
S'il vous plaît ne pas utiliser comprennent, utilisez un module plus petit pour qu'au lieu. Include est un insert de texte de code source qui n'est pas vérifiée par le compilateur au même niveau que le module d'utilisation, voir: FORTRAN: Différence entre les modules et INCLUENT . Include
rend généralement plus difficile pour les humains et l'ordinateur pour utiliser le code qui signifie qu'il ne doit pas être utilisé. Ex. de mpi-forum: « L'utilisation du mpif.h fichier include est fortement déconseillée et peut être dépréciée dans une future version de MPI. » ( http://mpi-forum.org/docs/mpi -3,1 / mpi31-rapport / node411.htm ).
Je sais que je suis un peu en retard à la fête, mais si vous êtes seulement après une série de constantes et non nécessairement des valeurs calculées, vous pouvez faire comme C et de créer un fichier include:
dans un fichier, par exemple, constants.for
real, parameter :: pi = 3.14
real, parameter :: g = 6.67384e-11
...
program main
use module1, only : func1, subroutine1, func2
implicit none
include 'constants.for'
...
end program main
Sous la direction de supprimer « réel (4) », comme certains pensent qu'il est une mauvaise pratique.