Frage

Nehmen wir an, Sie haben ein Fortran 90-Modul mit viele von Variablen, Funktionen und Unterprogrammen.In deinem USE Aussage, welcher Konvention folgen Sie:

  1. Deklarieren Sie explizit, welche Variablen/Funktionen/Unterprogramme Sie mit dem verwenden , only : Syntax, wie z USE [module_name], only : variable1, variable2, ...?
  2. Legen Sie eine Decke ein USE [module_name]?

Einerseits die only -Klausel macht den Code etwas ausführlicher.Es zwingt Sie jedoch dazu, sich im Code zu wiederholen und wenn Ihr Modul Folgendes enthält viele von Variablen/Funktionen/Unterprogrammen beginnen die Dinge unruhig auszusehen.

Hier ist ein Beispiel:

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

AktualisierenHoffentlich sagt jemand so etwas wie „Fortran?Codieren Sie es einfach in C# neu!“ damit ich dich ablehnen kann.


Aktualisieren

Ich mag Tim Whitcombs Antwort, das Fortrans vergleicht USE modulename mit Pythons from modulename import *.Ein Thema, das schon einmal auf Stack Overflow war:

Daher neige ich zu einem Konsens, alle Elemente, die ich in einem Modul verwende, explizit anzugeben über

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

Und wie Stefano Borini erwähnt,

Wenn] Sie ein so großes Modul haben, dass Sie sich nur gezwungen fühlen, nur hinzuzufügen, bedeutet dies, dass Ihr Modul zu groß ist.Teile es auf.

War es hilfreich?

Lösung

Es ist eine Frage der Balance.

Wenn Sie nur ein paar Sachen aus dem Modul zu benutzen, ist es sinnvoll, wenn Sie hinzufügen, klar angeben, was Sie verwenden.

Wenn Sie eine Menge Sachen aus dem Modul verwenden, und geben wird nur durch eine Menge Sachen folgen, so macht es weniger Sinn. Sie sind im Grunde Rosinenpickerei, was Sie verwenden, aber die wahre Tatsache ist, dass Sie an diesem Modul als Ganzes abhängig sind.

Doch am Ende die beste Philosophie ist dieser: wenn Sie über Namespace Verschmutzung betroffen sind, und Sie haben ein Modul so groß, dass man sich gezwungen fühlen, nur noch hinzuzufügen, bedeutet das, dass Ihr Modul zu groß ist. Teilen Sie es.

Update: Fortran? recode es nur in Python;)

Andere Tipps

Früher habe ich nur use modulename tun - dann, wie meine Anwendung wuchs, fand ich es immer schwieriger, die Quelle zu Funktionen finden (ohne grep zu Drehen) - einige der anderen Code um das Büro floating verwendet immer noch eine ein -subroutine-per-Datei, die ihre eigenen Probleme hat, aber es macht es viel einfacher, einen Text-Editor zu verwenden, um den Code zu bewegen und schnell aufzuspüren, was Sie brauchen.

Dies Nach der Erfahrung, ich habe ein Konvertit worden mit use ... only wann immer möglich. Ich habe auch begonnen, Python Kommissionierung, und es auf die gleiche Weise wie from modulename import * anzuzeigen. Es gibt eine Menge von großen Dinge, die Module, die Sie geben, aber ich ziehe meine globalen Namensraum streng kontrolliert zu halten.

Ich beantworte die Frage hier nicht genau, sondern füge nur eine andere Lösung hinzu, die ich unter bestimmten Umständen als nützlich erachtet habe, wenn Sie aus irgendeinem Grund Ihr Modul nicht aufteilen möchten und es zu Namespace-Konflikten kommt.Sie können abgeleitete Typen verwenden, um mehrere Namespaces in einem Modul zu speichern.

Wenn es eine logische Gruppierung der Variablen gibt, können Sie für jede Gruppe einen eigenen abgeleiteten Typ erstellen, eine Instanz dieses Typs im Modul speichern und dann genau die Gruppe importieren, die Sie gerade benötigen.

Kleines Beispiel:Wir haben viele Daten, von denen einige Benutzereingaben sind und andere das Ergebnis verschiedener Initialisierungen sind.

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

Wenn nun ein Unterprogramm nur Daten von verwendet init, importieren Sie genau das:

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

Dies ist definitiv keine universell anwendbare Lösung. Sie erhalten eine zusätzliche Ausführlichkeit durch die Syntax des abgeleiteten Typs und dann wird es natürlich kaum helfen, wenn Ihr Modul nicht dies ist basicdata oben sortieren, aber eher a allthestuffivebeenmeaningtosortoutVielfalt.Wie auch immer, ich hatte etwas Glück dabei, Code zu bekommen, der auf diese Weise leichter ins Gehirn passt.

Der Hauptvorteil der Nutzung, nur für mich ist, dass es mit Sachen meines globalen Namensraum verschmutzen vermeidet brauche ich nicht.

Einverstanden mit den meisten Antworten vorher gegeben, use ..., only: ... ist die Art und Weise, Typen Gebrauch zu gehen, wenn es sinnvoll ist, gelten python denken so viel wie möglich . Ein weiterer Vorschlag ist angemessen Namenskonventionen in importierten Modul zu verwenden, zusammen mit private / public Aussagen.

Zum Beispiel der netcdf Bibliothek verwendet nf90_<some name>, die die Namespace Verschmutzung auf der Importseite begrenzt.

use netcdf  ! imported names are prefixed with "nf90_"

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

ähnlich, der ncio Wrapper zu dieser Bibliothek verwendet nc_<some name> (nc_read, nc_write ...) .

Wichtig ist, dass mit solchen Konstruktionen, bei denen use: ..., only: ... weniger relevant gemacht wird, sollten Sie besser den Namensraum des importierten Moduls durch die Festlegung geeigneten private steuern würden / public Attribut im Header, so dass ein kurzer Blick auf es für die Leser ausreichend sein wird, die Ebene der „Verschmutzung“ beurteilen sie konfrontiert sind. Dies ist im Grunde die gleiche wie use ..., only: ..., aber auf der Modulseite importiert -. Also nur einmal geschrieben werden, nicht bei jedem Import)

Ein weitere Sache: so weit wie Objektorientierung und Python betroffen sind, ein Unterschied in meiner Ansicht ist, dass Fortran nicht wirklich typgebundene Prozeduren, teilweise fördern, weil es ein relativ neuer Standard (zB nicht kompatibel mit a Anzahl von Werkzeugen und weniger rational, ist es nur ungewöhnlich ist) und weil es praktisch Verhalten wie Verfahren frei abgeleiteten Typ Kopie (type(mytype) :: t1, t2 und t2 = t1) bricht. Das heißt, Sie müssen oft die Art importieren und alle Möchtegern-typgebundene Prozeduren, statt nur die Klasse. Dies allein macht Fortran Code ausführlicher im Vergleich zu Python und praktische Lösungen wie ein Präfix-Namenskonvention in handlichen kommen können.

IMO, die untere Zeile ist: wählen Sie Ihren Coding-Style für Leute, die es lesen werden (dies schließt Sie später selbst), wie von Python gelehrt. Das Beste ist die ausführlichere use ..., only: ... bei jedem Import, aber in einigen Fällen eine einfache Namenskonvention wird es tun (wenn Sie diszipliniert genug sind ...).

Ja, bitte benutzen use module, only: .... Für große Code-Basen mit mehreren Programmierern, macht es den Code leichter von jedermann zu folgen (oder einfach nur benutzen grep).

Bitte verwenden Sie nicht enthalten, ein kleineres Modul für diese stattdessen verwenden. Einschliessen ist ein Text einfügen des Quellcodes, die nicht durch den Compiler auf dem gleichen Niveau wie die Verwendung Modul aktiviert ist, finden Sie unter: Fortran: Unterschied zwischen BEINHALTEN und Modulen . Include macht es auch schwieriger für Menschen und Computer, den Code zu verwenden, das heißt, es sollte nicht verwendet werden. Ex. von mpi-Forum: „Die Verwendung der mpif.h Include-Datei wird dringend abgeraten und kann in einer zukünftigen Version von MPI veraltet.“ ( http://mpi-forum.org/docs/mpi -3.1 / mpi31-report / node411.htm ).

Ich weiß, ich bin ein wenig spät zur Party, aber wenn man erst nach einer Reihe von Konstanten und nicht unbedingt berechneten Werte sind, können Sie wie C zu tun, und erstellen Sie eine Include-Datei:

innerhalb einer Datei, z.B. 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

Edited "real (4)" zu entfernen, wie einige denken, es schlechte Praxis ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top