Domanda

Supponiamo che tu abbia un modulo Fortran 90 contenente molti di variabili, funzioni e subroutine.Nel tuo USE dichiarazione, quale convenzione segui:

  1. dichiara esplicitamente quali variabili/funzioni/subroutine stai utilizzando con , only : sintassi, come ad es USE [module_name], only : variable1, variable2, ...?
  2. Inserisci una coperta USE [module_name]?

Da un lato, il only La clausola rende il codice un po' più dettagliato.Tuttavia, ti costringe a ripeterti nel codice e se il tuo modulo contiene molti di variabili/funzioni/subroutine, le cose cominciano a sembrare indisciplinate.

Ecco un esempio:

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

AggiornamentoSperiamo che qualcuno dica qualcosa del genere "Fortran?Basta ricodificarlo in C#!" quindi posso votarti in basso.


Aggiornamento

mi piace La risposta di Tim Whitcomb, che confronta quello di Fortran USE modulename con Python from modulename import *.Un argomento già presente su Stack Overflow:

  • "importa modulo" o "da modulo importa"

    • In una risposta, Mark Roddy ha menzionato:

      non utilizzare 'from module import *'.Per qualsiasi ampio set di codice ragionevole, se "importa *" probabilmente lo cementa nel modulo, incapace di essere rimosso.Questo perché è difficile determinare quali elementi usati nel codice provengono dal "modulo", rendendo a est per arrivare al punto in cui pensi di non usare più l'importazione ma è estremamente difficile essere sicuri.

  • Quali sono le buone regole pratiche per le importazioni di Python?

    • la risposta di dbr contiene

      Non fare da X import * - Rende il tuo codice molto difficile da capire, poiché non puoi vedere facilmente da dove proviene un metodo (da X import *;da y import *;my_func () - dove viene definito my_func?)

Quindi, sono propenso a un consenso nel dichiarare esplicitamente tutti gli elementi che sto utilizzando in un modulo tramite

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

E come Stefano Borini cita,

Se] hai un modulo così grande che ti senti costretto ad aggiungere solo, significa che il tuo modulo è troppo grande.Dividilo.

È stato utile?

Soluzione

E 'una questione di equilibrio.

Se si utilizza solo un paio di cose dal modulo, ha senso se si aggiunge solo, per specificare in modo chiaro ciò che si sta utilizzando.

Se si utilizza un sacco di cose dal modulo, specificando solo sarà seguita da un sacco di roba, quindi ha meno senso. Tu sei fondamentalmente cherry-picking quello che si utilizza, ma il fatto vero è che siete dipendenti da quel modulo nel suo complesso.

Tuttavia, alla fine il migliore filosofia è questa: se siete preoccupati per l'inquinamento dello spazio dei nomi, e si dispone di un modulo così grande che si sente in dovere di aggiungere solo, significa che il modulo è troppo grande. Split.

Aggiornamento: Fortran? solo ricodificare in python;)

Altri suggerimenti

ho usato per fare proprio use modulename - allora, come la mia domanda è cresciuta, l'ho trovato sempre più difficile da trovare la fonte di funzioni (senza girare a grep) - alcuni dei altro codice che galleggia intorno all'ufficio utilizza ancora uno -subroutine-per-file, che ha una propria serie di problemi, ma rende molto più facile da usare un editor di testo per passare attraverso il codice e rapidamente rintracciare quello che ti serve.

Dopo aver sperimentato questo, sono diventato un convertito al utilizzando use ... only quando possibile. Ho anche iniziato a raccogliere Python, e vederlo allo stesso modo di from modulename import *. Ci sono un sacco di grandi cose che ti danno i moduli, ma preferisco mantenere il mio namespace globale strettamente controllato.

Non rispondo esattamente alla domanda qui, sto solo inserendo un'altra soluzione che ho trovato utile in alcune circostanze, se per qualsiasi motivo non vuoi dividere il tuo modulo e iniziare a ricevere conflitti nello spazio dei nomi.È possibile utilizzare tipi derivati ​​per archiviare diversi spazi dei nomi in un modulo.

Se esiste un raggruppamento logico delle variabili, puoi creare il tuo tipo derivato per ciascun gruppo, memorizzare un'istanza di questo tipo nel modulo e quindi puoi importare solo il gruppo di cui hai bisogno.

Piccolo esempio:Abbiamo molti dati, alcuni dei quali sono input dell'utente e altri sono il risultato di inizializzazioni varie.

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

Ora, se una subroutine utilizza solo i dati da init, importi proprio questo:

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

Questa non è sicuramente una soluzione universalmente applicabile, ottieni un po' di verbosità extra dalla sintassi del tipo derivato e quindi ovviamente sarà di scarso aiuto se il tuo modulo non è quello basicdata ordina sopra, ma invece più di a allthestuffivebeenmeaningtosortoutvarietà.Ad ogni modo, ho avuto un po' di fortuna nell'ottenere codice che si adatta più facilmente al cervello in questo modo.

Il principale vantaggio di utilizzo, solo per me è che evita inquinare il mio namespace globale con roba non ho bisogno.

Concordo con la maggior parte delle risposte fornite in precedenza, use ..., only: ... è la strada da percorrere, usa i tipi quando ha senso, applica pensiero pitone per quanto possibile.Un altro suggerimento è quello di utilizzare convenzioni di denominazione appropriate nel modulo importato, insieme a private / public dichiarazioni.

Ad esempio, il netcdf usi della biblioteca nf90_<some name>, che limita l'inquinamento dello spazio dei nomi da parte dell'importatore.

use netcdf  ! imported names are prefixed with "nf90_"

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

allo stesso modo, il nci wrapper per questa libreria utilizza nc_<some name> (nc_read, nc_write...).

È importante sottolineare che con tali progetti dove use: ..., only: ... viene reso meno rilevante, è meglio controllare lo spazio dei nomi del modulo importato impostando il file appropriate private / public attributi nell'intestazione, così che ai lettori basterà una rapida occhiata per valutare quale livello di "inquinamento" si trovano ad affrontare.Questo è fondamentalmente lo stesso di use ..., only: ..., ma sul lato del modulo importato - quindi da scrivere solo una volta, non ad ogni importazione).

Un'altra cosa:per quanto riguarda l'orientamento agli oggetti e Python, una differenza a mio avviso è che Fortran non incoraggia realmente le procedure legate al tipo, in parte perché è uno standard relativamente nuovo (ad es.non compatibile con una serie di strumenti e, in modo meno razionale, è semplicemente insolito) e perché interrompe comportamenti pratici come la copia di tipo derivato senza procedure (type(mytype) :: t1, t2 E t2 = t1).Ciò significa che spesso è necessario importare il tipo e tutte le potenziali procedure legate al tipo, anziché solo la classe.Questo da solo rende il codice Fortran più dettagliato rispetto a Python e soluzioni pratiche come una convenzione di denominazione del prefisso possono tornare utili.

Secondo me, il punto è:scegli il tuo stile di codifica per le persone che lo leggeranno (questo include te stesso in seguito), come insegnato da Python.Il migliore è il più dettagliato use ..., only: ... ad ogni importazione, ma in alcuni casi basterà una semplice convenzione di denominazione (se sei abbastanza disciplinato...).

Sì, si prega di utilizzare use module, only: .... Per basi di codice di grandi dimensioni con più programmatori, rende il codice più facile da seguire da tutti (o semplicemente utilizzare grep).

Si prega di non utilizzare includono, utilizzare un modulo più piccolo per che, invece. Includi è un inserto del testo del codice sorgente, che non viene controllato dal compilatore allo stesso livello di modulo di uso, consultare: FORTRAN: Differenza tra inclusione ed i moduli . Include generalmente rende più difficile per gli esseri umani e computer di utilizzare il codice che significa che non deve essere utilizzato. Ex. da mpi-forum: "L'uso del mpif.h file include è fortemente sconsigliato e può essere obsoleto in una futura versione di MPI." ( http://mpi-forum.org/docs/mpi -3.1 / mpi31-report / node411.htm ).

Lo so che sono un po 'in ritardo alla festa, ma se siete solo dopo una serie di costanti e non necessariamente i valori calcolati, si potrebbe fare come il C e creare un file di inclusione:

all'interno di un file, per esempio, 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

A cura di rimuovere "reale (4)", come alcuni pensano che è una cattiva pratica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top