Как вы используете данные модуля Fortran 90 - PullRequest
34 голосов
/ 06 августа 2009

Допустим, у вас есть модуль Fortran 90, содержащий лотов переменных, функций и подпрограмм. В вашем USE заявлении, какое соглашение вы придерживаетесь:

  1. явно объявляет, какие переменные / функции / подпрограммы вы используете с синтаксисом , only :, например USE [module_name], only : variable1, variable2, ...?
  2. Вставить одеяло USE [module_name]?

С одной стороны, предложение only делает код более многословным. Однако это заставляет вас повторяться в коде, и если ваш модуль содержит лотов переменных / функций / подпрограмм, все начинает выглядеть неуправляемым.

Вот пример:

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

Update Надеюсь, кто-то скажет что-то вроде «Фортран? Просто перекодируй это в C #!» , чтобы я мог проголосовать за тебя.


Обновление

Мне нравится Ответ Тима Уиткомба , который сравнивает Фортран USE modulename с Питоном from modulename import *. Тема, которая ранее была переполнена стеком:

  • ‘модуль импорта’ или module из модуля импорта ’

    • В ответе Марк Родди упомянул:

      не использовать 'из модуля импорта *'. За любой разумный большой набор кода, если вы «импортируете *», скорее всего, цементировать его в модуль, не может быть удаленным. Это потому что трудно определить, какие предметы используются в коде приходят из «модуля», сделать это на восток, чтобы добраться до сути где вы думаете, что вы не используете импортировать больше, но его чрезвычайно Трудно быть уверенным.

  • Каковы хорошие практические правила для импорта Python?

    • ответ dbr содержит

      не делать из x import * - это делает Ваш код очень трудно понять, так как Вы не можете легко увидеть, где метод пришел из (из x import *; из y Импортировать *; my_func () - где my_func определяется?)

Итак, я склоняюсь к консенсусу в отношении явного указания всех элементов, которые я использую в модуле, через

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

И как Стефано Борини упоминает ,

[если] у вас такой большой модуль, что вы чувствовать себя вынужденным добавить ТОЛЬКО, это означает, что ваш модуль слишком большой. Разделите это.

Ответы [ 7 ]

25 голосов
/ 06 августа 2009

Раньше я просто делал use modulename - затем, когда мое приложение росло, мне становилось все труднее находить исходный код для функций (не обращаясь к grep) - часть другого кода, распространяющегося по офису, все еще использует одна подпрограмма на файл, которая имеет свой собственный набор проблем, но она значительно упрощает использование текстового редактора для перемещения по коду и быстрого отслеживания того, что вам нужно.

После этого я стал использовать use ... only, когда это возможно. Я также начал собирать Python и просматривать его так же, как from modulename import *. Множество замечательных вещей дают вам модули, но я предпочитаю строго контролировать свое глобальное пространство имен.

15 голосов
/ 06 августа 2009

Это вопрос баланса.

Если вы используете только несколько вещей из модуля, имеет смысл, если вы добавите ТОЛЬКО, чтобы четко указать, что вы используете.

Если вы используете много материала из модуля, за указанием ТОЛЬКО последует много материала, так что это имеет меньше смысла. Вы в основном выбираете то, что используете, но на самом деле вы зависите от этого модуля в целом.

Однако, в конце концов, лучшая философия такова: если вас беспокоит загрязнение пространства имен, и у вас есть модуль настолько большой, что вы чувствуете необходимость добавлять ТОЛЬКО, это означает, что ваш модуль слишком большой. Разделите это.

Обновление: Фортран? просто перекодировать его в python;)

6 голосов
/ 11 марта 2011

Не совсем отвечая на вопрос здесь, просто добавляю другое решение, которое я нашел полезным в некоторых обстоятельствах, если по какой-то причине вы не хотите разделять свой модуль и начать получать конфликты пространства имен. Вы можете использовать производные типы для хранения нескольких пространств имен в одном модуле.

Если существует некоторая логическая группировка переменных, вы можете создать свой собственный производный тип для каждой группы, сохранить экземпляр этого типа в модуле, а затем вы можете импортировать только ту группу, которая вам нужна.

Небольшой пример: у нас есть много данных, некоторые из которых являются пользовательскими, а некоторые - результатом разных инициализаций.

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

Теперь, если подпрограмма использует только данные из init, вы импортируете только это:

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

Это определенно не универсально применимое решение, вы получаете некоторую дополнительную многословность от синтаксиса производного типа, и тогда это, конечно, вряд ли поможет, если ваш модуль не является basicdata сортировкой выше, а вместо этого allthestuffivebeenmeaningtosortout разнообразие. В любом случае, мне посчастливилось получить код, который таким образом легче вписывается в мозг.

4 голосов
/ 06 августа 2009

Основным преимуществом ИСПОЛЬЗОВАНИЯ, ТОЛЬКО для меня, является то, что он избегает загрязнения моего глобального пространства имен вещами, которые мне не нужны.

1 голос
/ 09 мая 2016

Да, пожалуйста, используйте use module, only: .... Для больших баз кода с несколькими программистами это облегчает понимание кода всеми (или просто использование grep).

Пожалуйста, не используйте include, используйте для этого меньший модуль. Включить - это текстовая вставка исходного кода, которая не проверяется компилятором на том же уровне, что и модуль использования, см .: FORTRAN: Разница между INCLUDE и модулями . Include как правило, людям и компьютерам труднее использовать код, что означает, что его нельзя использовать. Ex. с mpi-forum: «Использование файла включения mpif.h настоятельно не рекомендуется и может быть исключено в будущей версии MPI». (http://mpi -forum.org / документы / МПИ-3,1 / mpi31-отчет / node411.htm ).

1 голос
/ 12 декабря 2015

Согласившись с большинством ранее полученных ответов, use ..., only: ... - это путь, используйте типы, когда это имеет смысл, максимально примените мышление питона . Еще одно предложение - использовать соответствующие соглашения об именах в импортированном модуле вместе с private / public операторами.

Например, библиотека netcdf использует nf90_<some name>, что ограничивает загрязнение пространства имен на стороне импортера.

use netcdf  ! imported names are prefixed with "nf90_"

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

аналогично, оболочка ncio для этой библиотеки использует nc_<some name> (nc_read, nc_write ...).

Важно отметить, что в таких проектах, где use: ..., only: ... сделан менее актуальным, вам лучше контролировать пространство имен импортируемого модуля, задав соответствующие атрибуты private / public в заголовке, чтобы быстро взглянуть на него будет достаточно для читателей, чтобы оценить, с каким уровнем «загрязнения» они сталкиваются. По сути, это то же самое, что и use ..., only: ..., но на стороне импортированного модуля - поэтому записывается только один раз, а не при каждом импорте).

Еще одна вещь: что касается объектной ориентации и python, на мой взгляд, различие заключается в том, что Фортран на самом деле не поощряет процедуры с привязкой к типу, отчасти потому, что это относительно новый стандарт (например, не совместимый с количество инструментов, и менее рационально, это просто необычно), и потому что это нарушает удобное поведение, такое как безпроцессное копирование производного типа (type(mytype) :: t1, t2 и t2 = t1). Это означает, что вам часто приходится импортировать тип и все возможные процедуры с привязкой к типу, а не просто класс. Уже одно это делает код на Fortran более многословным по сравнению с Python, и практические решения, такие как соглашение о присвоении имен префиксам, могут оказаться полезными.

ИМО, суть в том, что выбирайте свой стиль кодирования для людей, которые будут его читать (включая ваше позднее «я»), как учит Python. Лучшим является более подробное use ..., only: ... при каждом импорте, но в некоторых случаях это будет делать простое соглашение об именах (если вы достаточно дисциплинированы ...).

0 голосов
/ 21 ноября 2014

Я знаю, что немного опоздал на вечеринку, но если вы только после набора констант и не обязательно вычисленных значений, вы можете сделать как C и создать файл включения:

внутри файла, например, константы для

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

Отредактировано, чтобы удалить "real (4)", так как некоторые думают, что это плохая практика.

...