Допустим, у вас есть модуль 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 #!» , чтобы я мог проголосовать против вас.


Обновить

Мне нравится ответ Тима Уиткомба, который сравнивает USE modulename Фортрана с from modulename import * Python. Тема, которая раньше была на Stack Overflow:

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

    • В ответе Марк Родди отметил: <цитата>

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

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

    • ответ dbr содержит <цитата>

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

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

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

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

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

38
Pete 6 Авг 2009 в 22:06

7 ответов

Лучший ответ

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

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

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

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

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

18
Stefano Borini 6 Авг 2009 в 21:07

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

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

27
Tim Whitcomb 6 Авг 2009 в 18:51

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

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

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

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

6
TorbjornB 11 Мар 2011 в 08:10

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

4
ire_and_curses 6 Авг 2009 в 18:16

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

1
Mahé 12 Дек 2015 в 11:58

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

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

1
Community 23 Май 2017 в 11:54

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

Внутри файла, например, 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

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

0
Forrest 21 Ноя 2014 в 19:36