Вопрос

Допустим, у вас есть модуль 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

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


Обновить

Мне нравится Ответ Тима Уиткомба, который сравнивает Fortran's USE modulename с помощью Python from modulename import *.Тема, которая ранее была посвящена переполнению стека:

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

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

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

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

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

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

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

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

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

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разнообразие.Во всяком случае, мне немного повезло в получении кода, который таким образом легче укладывается в мозгу.

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

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

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

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

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

Я знаю, что немного опоздал на вечеринку, но если вам нужен только набор констант и не обязательно вычисляемые значения, вы могли бы сделать что-то вроде 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)", поскольку некоторые считают, что это плохая практика.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top