Является ли if(interactive()) R эквивалентом Python "if __name__ ==" __main__ ": main()"?

Я хотел бы, чтобы R-скрипты имели функцию main(), которая выполняется в интерактивном режиме. Но функция main() не должна выполняться при поиске файла.

Уже есть вопрос по этому поводу, и очень хороший ответ предлагает использовать функцию interactive(). Однако это не работает для меня. У меня недостаточно очков репутации, чтобы комментировать или отвечать на этот вопрос. Поэтому я задаю вопрос здесь снова.

Я пишу это в script_1.r

if(interactive()){
  your main code here
}

Если я использую Knitr, чтобы отказаться от HTML или PDF-документа, поиск сценария. Этот код под if(interactive()) не будет выполнен Это хорошо для меня, это то, что я хочу.

Моя проблема в том, что если я source("script_1.r") от script_2.r в интерактивном режиме он все равно будет запускать код под этим if(interactive()) часть.

3 ответа

Решение

Лучший способ получить тот вид контроля, который вы ищете, это использовать опции.

Например, "script.r" будет выглядеть так:

main <- function() {
    message('main!')
}

if (getOption('run.main', default=TRUE)) {
   main()
}

Если вы используете файл в интерактивном режиме и не хотите main выполнить, просто позвоните options(run.main=FALSE) прежде чем позвонить source, Если вы используете скрипт с knitr и хотите main выполнить, не устанавливайте опцию, и по умолчанию TRUE, Или, если вы не хотите, чтобы основной работал с knitr, позвоните options(run.main=FALSE) прежде чем позвонить.

Как вы заметили, нет, это не одно и то же. if(interactive()) делает именно то, что говорит название - он проверяет, выполняется ли код в интерактивной оболочке. Не больше, не меньше.

Там нет прямого эквивалента if __name__ == '__main__' из Python в R, так как R не имеет понятия модулей так же, как Python, и sourceкод выполняется только напрямую.

Вы можете написать свой собственный source Команда, чтобы заменить по умолчанию и выполнить необходимую проверку, однако.

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

Я нашел еще один способ, который будет работать так, как вы описали, без необходимости использования и изменения параметров:

      if (sys.nframe() == 0) {
    # ... do main stuff
}

равно0при запуске из интерактивного терминала или с помощьюRscript.exe, и в этом случае запустится основной код. В противном случае, когда кодsourceд,sys.nframe()равно4(в моем случае, не уверен, как именно это работает), что предотвратит запуск основного кода.

источник

Другие вопросы по тегам