Подтвердить что ты не робот

Как вы используете данные модуля Fortran 90

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

  • явно объявлять, какие переменные/функции/подпрограммы вы используете с синтаксисом , only :, например USE [module_name], only : variable1, variable2, ...?
  • Вставьте защитное покрытие 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

Обновление Надеюсь, кто-то скажет что-то вроде "Fortran? Просто перекодируйте его на С#!" поэтому я могу проголосовать за вас.


Обновление

Мне нравится Tim Whitcomb answer, в котором сравнивается Fortran USE modulename с Python from modulename import *. Тема, которая была ранее перенесена в стек:

  • 'импортировать модуль или' из импорта модуля

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

      не использовать 'из импорта модуля *. Для любой разумный большой набор кода, если вы импортируете *, ваша вероятность будет закрепляя его в модуле, не удалось для удаления. Это потому, что это трудно определить, какие предметы используются в коде поступают из "модуля", делая его на восток, чтобы добраться до точки где вы думаете, что не используете больше, но его чрезвычайно трудно быть уверенным.

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

    • dbr answer содержит

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Обновление: Fortran? просто перекодируйте его в python;)

Ответ 2

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

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

Ответ 3

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

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

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

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

Главное преимущество USE, ТОЛЬКО для меня, заключается в том, что он позволяет избежать загрязнения моего глобального пространства имен теми вещами, которые мне не нужны.

Ответ 5

Соглашаясь с большинством ответов, которые были даны ранее, use ..., only: ... - это способ пойти, использовать типы, когда это имеет смысл, применять python thinking столько же насколько это возможно. Другое предложение - использовать соответствующие соглашения об именах в импортированном модуле вместе с операторами 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 разница в моем представлении заключается в том, что fortran действительно не поощряет процедуры привязки к типу, отчасти потому, что это относительно новый стандарт (например, несовместимый с количество инструментов и менее рационально, это просто необычно) и потому, что он разрушает удобное поведение, такое как копирование производного типа без процедур (type(mytype) :: t1, t2 и t2 = t1). Это означает, что вам часто приходится импортировать тип и все возможные процедуры привязки к типу, а не только класс. Это само по себе делает fortran-код более подробным по сравнению с python, и практические решения, такие как соглашение об именах префиксов, могут пригодиться.

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

Ответ 6

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

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

Ответ 7

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

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

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)", поскольку некоторые считают, что это плохая практика.