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