Jak korzystać z danych modułu Fortran 90

Załóżmy, że masz moduł Fortran 90 zawierający wiele zmiennych, funkcji i podprogramów. W twoim USE oświadczeniu, którą konwencję stosujesz:

  1. jawnie zadeklaruj, jakich zmiennych / funkcji / podprogramów używasz ze składnią , only :, np. USE [module_name], only : variable1, variable2, ...?
  2. wstawić koc USE [module_name]?

Z jednej strony klauzula only sprawia, że kod jest nieco bardziej gadatliwy. Zmusza jednak do powtórzenia się w kodzie i jeśli twój moduł zawiera wiele zmiennych / funkcji / podprogramów, rzeczy zaczynają wyglądać niesfornie.

Oto przykład:

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

Aktualizacja Mam nadzieję, że ktoś powie coś w stylu "Fortran? Wystarczy przekodować w C#!" więc mogę cię przegłosować.


Update

Podoba mi się odpowiedź Tima Whitcomba , która porównuje FortranaUSE modulename z Pythonem from modulename import *. Temat, który był na Stack Overflow przed:
  • 'import module" lub "from module import"

    • W odpowiedzi Mark Roddy wspomniał:

      Nie używaj 'from module import *'. Na każdy rozsądny duży zbiór kodu, jeśli "importujesz *" prawdopodobnie będzie cementowanie go w module, nie można do usunięcia. To dlatego, że jest trudne do określenia, jakie elementy używane w kodzie pochodzą z "modułu", / align = "left" / where you think nie używasz import już, ale jego niezwykle trudno być pewnym.

  • Jakie są dobre zasady importowania Pythona?

    • odpowiedź dbr zawiera

      Don ' t do from X import * - it makes Twój kod bardzo trudny do zrozumienia, jak nie widać łatwo, gdzie metoda came from (from X import *; from y import *; my_func () - gdzie jest my_func zdefiniowany?)

Skłaniam się więc ku konsensusowi, w którym wyraźnie stwierdzam wszystkie elementy, których używam w module za pośrednictwem

USE modulename, only : var1, var2, ...

I jak wspomina Stefano Borini,

[Jeśli] masz moduł tak duży, że Poczuj się zmuszony do dodania tylko, oznacza to, że że Twój moduł jest za duży. Podziel się.

Author: Community, 2009-08-06

7 answers

To kwestia równowagi.

Jeśli używasz tylko kilku rzeczy z modułu, sensowne jest dodanie tylko, aby jasno określić, czego używasz.

Jeśli używasz wielu rzeczy z modułu, podanie tylko będzie poprzedzone wieloma rzeczami, więc ma to mniej sensu. Jesteś w zasadzie cherry-wybierając to, czego używasz, ale prawda jest taka, że jesteś zależny od tego modułu jako całości.

Jednak w końcu najlepszą filozofią jest ta: Jeśli martwisz się o zanieczyszczenie przestrzeni nazw, a masz moduł tak duży, że czujesz się zmuszony do dodania tylko, oznacza to, że Twój moduł jest zbyt duży. Podziel się.

Update: Fortran? po prostu przekoduj to w Pythonie;)

 15
Author: Stefano Borini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-06 21:07:21

Kiedyś po prostu robiłem use modulename - potem, gdy moja aplikacja się rozrastała, coraz trudniej było znaleźć źródło funkcji (bez włączania grepa) - niektóre z innych kodów unoszących się po biurze nadal używają jednego podprogramu na plik, który ma swój własny zestaw problemów, ale znacznie ułatwia korzystanie z edytora tekstu, aby poruszać się po kodzie i szybko znaleźć to, czego potrzebujesz.

Po doświadczeniu tego, stałem się konwerterem na użycie use...only w miarę możliwości. Zacząłem też odbierać Pythona i oglądać go w ten sam sposób co from modulename import *. Jest wiele wspaniałych rzeczy, które dają Ci Moduły, ale wolę, aby moja globalna przestrzeń nazw była ściśle kontrolowana.

 24
Author: Tim Whitcomb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-06 18:51:37

Nie do końca odpowiadam na to pytanie, po prostu wprowadzam inne rozwiązanie, które uznałem za przydatne w pewnych okolicznościach, jeśli z jakiegoś powodu nie chcesz podzielić modułu i zacząć otrzymywać starć przestrzeni nazw. Możesz używać typów pochodnych do przechowywania kilku przestrzeni nazw w jednym module.

Jeśli istnieje logiczne grupowanie zmiennych, możesz utworzyć własny typ Pochodny dla każdej grupy, zapisać instancję tego typu w module, a następnie zaimportować tylko grupę, która tak się składa, że potrzebujesz.

Mały przykład: mamy dużo danych, z których część jest wprowadzana przez użytkownika, a część jest wynikiem różnych inicjalizacji.

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

Teraz, jeśli podprogram używa tylko danych z init, importujesz tylko to:

subroutine doesstuff
   use basicdata, only : init
   ...
   q = init%b
end subroutine doesstuff

To zdecydowanie nie jest uniwersalne rozwiązanie, otrzymujesz dodatkową szczegółowość ze składni typu pochodnego, a to oczywiście nie pomoże, jeśli twój moduł nie jest typem basicdata powyżej, ale zamiast tego bardziej odmianą allthestuffivebeenmeaningtosortout. W każdym razie, miałem trochę szczęścia w uzyskaniu kodu, który łatwiej pasuje do mózgu w ten sposób.

 6
Author: TorbjornB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-11 08:10:47

Główną zaletą użycia, tylko dla mnie, jest to, że unika zanieczyszczania mojej globalnej przestrzeni nazw rzeczami, których nie potrzebuję.

 3
Author: ire_and_curses,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-06 18:16:24

Zgadzam się z większością wcześniej udzielonych odpowiedzi, use ..., only: ... jest droga do zrobienia, użyj typów, gdy ma to sens, zastosuj myślenie Pythona jak najwięcej. Kolejną sugestią jest użycie odpowiednich konwencji nazewnictwa w importowanym module, wraz z private / public Oświadczenia.

Na przykład Biblioteka netcdf używa nf90_<some name>, co ogranicza zanieczyszczenie przestrzeni nazw po stronie importera.

use netcdf  ! imported names are prefixed with "nf90_"

nf90_open(...)
nf90_create(...)
nf90_get_var(...)
nf90_close(...)

Podobnie, ncio wrapper do tej biblioteki używa nc_<some name> (nc_read, nc_write...).

Co ważne, przy takich projektach, gdzie use: ..., only: ... jest mniej istotne, lepiej kontrolować przestrzeń nazw importowanego modułu, ustawiając odpowiednie private / public atrybutów w nagłówku, tak aby szybkie jego obejrzenie wystarczyło czytelnikom do oceny z jakim poziomem "zanieczyszczenia" się borykają. Jest to w zasadzie to samo co use ..., only: ..., ale po stronie importowanego modułu-tak więc może być napisane tylko raz, nie przy każdym imporcie).

Jeszcze jedno: o ile orientacja obiektowa i python są zaniepokojone, różnica w moim przekonaniu jest taka, że fortran nie zachęca do procedur związanych z typami, po części dlatego, że jest to stosunkowo nowy standard (np. nie kompatybilny z wieloma narzędziami, a mniej racjonalnie, jest to po prostu niezwykłe) i ponieważ łamie poręczne zachowanie, takie jak wolna od procedur pochodna Kopia typu (type(mytype) :: t1, t2 i t2 = t1). Oznacza to, że często musisz zaimportować typ i wszystkie możliwe procedury związane z typem, zamiast tylko klasy. To samo sprawia, że kod fortran jest bardziej zwięzły w porównaniu z Pythonem, a praktyczne rozwiązania, takie jak konwencja nazewnictwa prefiksów, mogą się przydać.

IMO, najważniejsze jest to: wybierz swój styl kodowania dla osób, które go przeczytają (dotyczy to również twojego późniejszego ja), zgodnie z nauczaniem Pythona. Najlepsze jest bardziej wyraziste use ..., only: ... przy każdym imporcie, ale w niektórych przypadkach wystarczy zwykła konwencja nazewnictwa (jeśli jesteś wystarczająco zdyscyplinowany...).

 1
Author: Mahé,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-12 11:58:37

Tak, proszę użyć use module, only: .... W przypadku dużych baz kodu z wieloma programistami, kod jest łatwiejszy do naśladowania przez wszystkich (lub po prostu użyj grep).

Proszę nie używać include, zamiast tego użyj mniejszego modułu. Include jest tekstową wstawką kodu źródłowego, która nie jest sprawdzana przez kompilator na tym samym poziomie co use module, patrz: FORTRAN: Difference between INCLUDE and modules . Ogólnie utrudnia zarówno ludziom, jak i komputerowi użycie kodu, co oznacza, że powinien nie stosować. Ex. z mpi-forum: "korzystanie z mpif.H plik nagłówkowy jest zdecydowanie odradzany i może być przestarzały w przyszłej wersji MPI."( http://mpi-forum.org/docs/mpi-3.1/mpi31-report/node411.htm).

 1
Author: Knut Gjerden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:37

Wiem, że jestem trochę spóźniony na imprezę, ale jeśli chodzi Ci tylko o zbiór stałych i niekoniecznie obliczonych wartości, możesz zrobić jak C i utworzyć plik nagłówkowy:

Wewnątrz pliku, np. stałe.dla

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

Edytowano, aby usunąć " real (4)", ponieważ niektórzy uważają, że jest to zła praktyka.

 0
Author: Forrest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-21 19:36:02