Is there an R equivalent of the pythonic if __name__ == __main__: main()?
I think that the interactive()
function might work.
This function returns TRUE
when R is being used interactively and FALSE
otherwise. So just use if (interactive())
i.e. the equivalent is
if (!interactive()) {
main()
}
What does if __name__ == __main__: do?
Short Answer
It's boilerplate code that protects users from accidentally invoking the script when they didn't intend to. Here are some common problems when the guard is omitted from a script:
If you import the guardless script in another script (e.g.
import my_script_without_a_name_eq_main_guard
), then the latter script will trigger the former to run at import time and using the second script's command line arguments. This is almost always a mistake.If you have a custom class in the guardless script and save it to a pickle file, then unpickling it in another script will trigger an import of the guardless script, with the same problems outlined in the previous bullet.
Long Answer
To better understand why and how this matters, we need to take a step back to understand how Python initializes scripts and how this interacts with its module import mechanism.
Whenever the Python interpreter reads a source file, it does two things:
it sets a few special variables like
__name__
, and thenit executes all of the code found in the file.
Let's see how this works and how it relates to your question about the __name__
checks we always see in Python scripts.
Code Sample
Let's use a slightly different code sample to explore how imports and scripts work. Suppose the following is in a file called foo.py
.
# Suppose this is foo.py.
print("before import")
import math
print("before function_a")
def function_a():
print("Function A")
print("before function_b")
def function_b():
print("Function B {}".format(math.sqrt(100)))
print("before __name__ guard")
if __name__ == '__main__':
function_a()
function_b()
print("after __name__ guard")
Special Variables
When the Python interpreter reads a source file, it first defines a few special variables. In this case, we care about the __name__
variable.
When Your Module Is the Main Program
If you are running your module (the source file) as the main program, e.g.
python foo.py
the interpreter will assign the hard-coded string "__main__"
to the __name__
variable, i.e.
# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__"
When Your Module Is Imported By Another
On the other hand, suppose some other module is the main program and it imports your module. This means there's a statement like this in the main program, or in some other module the main program imports:
# Suppose this is in some other main program.
import foo
The interpreter will search for your foo.py
file (along with searching for a few other variants), and prior to executing that module, it will assign the name "foo"
from the import statement to the __name__
variable, i.e.
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"
Executing the Module's Code
After the special variables are set up, the interpreter executes all the code in the module, one statement at a time. You may want to open another window on the side with the code sample so you can follow along with this explanation.
Always
It prints the string
"before import"
(without quotes).It loads the
math
module and assigns it to a variable calledmath
. This is equivalent to replacingimport math
with the following (note that__import__
is a low-level function in Python that takes a string and triggers the actual import):
# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
It prints the string
"before function_a"
.It executes the
def
block, creating a function object, then assigning that function object to a variable calledfunction_a
.It prints the string
"before function_b"
.It executes the second
def
block, creating another function object, then assigning it to a variable calledfunction_b
.It prints the string
"before __name__ guard"
.
Only When Your Module Is the Main Program
- If your module is the main program, then it will see that
__name__
was indeed set to"__main__"
and it calls the two functions, printing the strings"Function A"
and"Function B 10.0"
.
Only When Your Module Is Imported by Another
- (instead) If your module is not the main program but was imported by another one, then
__name__
will be"foo"
, not"__main__"
, and it'll skip the body of theif
statement.
Always
- It will print the string
"after __name__ guard"
in both situations.
Summary
In summary, here's what'd be printed in the two cases:
# What gets printed if foo is the main program
before import
before function_a
before function_b
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before function_a
before function_b
before __name__ guard
after __name__ guard
Why Does It Work This Way?
You might naturally wonder why anybody would want this. Well, sometimes you want to write a .py
file that can be both used by other programs and/or modules as a module, and can also be run as the main program itself. Examples:
Your module is a library, but you want to have a script mode where it runs some unit tests or a demo.
Your module is only used as a main program, but it has some unit tests, and the testing framework works by importing
.py
files like your script and running special test functions. You don't want it to try running the script just because it's importing the module.Your module is mostly used as a main program, but it also provides a programmer-friendly API for advanced users.
Beyond those examples, it's elegant that running a script in Python is just setting up a few magic variables and importing the script. "Running" the script is a side effect of importing the script's module.
Food for Thought
Question: Can I have multiple
__name__
checking blocks? Answer: it's strange to do so, but the language won't stop you.Suppose the following is in
foo2.py
. What happens if you saypython foo2.py
on the command-line? Why?
# Suppose this is foo2.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def function_a():
print("a1")
from foo2 import function_b
print("a2")
function_b()
print("a3")
def function_b():
print("b")
print("t1")
if __name__ == "__main__":
print("m1")
function_a()
print("m2")
print("t2")
- Now, figure out what will happen if you remove the
__name__
check infoo3.py
:
# Suppose this is foo3.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def function_a():
print("a1")
from foo3 import function_b
print("a2")
function_b()
print("a3")
def function_b():
print("b")
print("t1")
print("m1")
function_a()
print("m2")
print("t2")
- What will this do when used as a script? When imported as a module?
# Suppose this is in foo4.py
__name__ = "__main__"
def bar():
print("bar")
print("before __name__ guard")
if __name__ == "__main__":
bar()
print("after __name__ guard")
Is if(interactive()) an R equivalent to the pythonic “if __name__ == ”__main__“: main()”?
The best way to get the kind of control you're looking for is to use options.
For instance, 'script.r' would look like this:
main <- function() {
message('main!')
}
if (getOption('run.main', default=TRUE)) {
main()
}
If you are sourcing the file in interactive mode and don't want main
to execute, simply call options(run.main=FALSE)
before you call source
. If you are using the script with knitr and you want main
to execute, don't set the option, and it will default to TRUE
. Or if you don't want the main to run with knitr, call options(run.main=FALSE)
before calling it.
Is There C equivalent to Python's: if __name__ == '__main__': to write main() at the top of the file?
You do need to make a forward declaration (if you want to keep main at start of file), as this code will be compiled and not executed. As the compiler compiles line by line, it won't know the signature of the function before reaching it.
People are used to develop more important functions at bottom of the file.
But how does compilation work ?
Compilation is in fact made in 2 steps.
1) Gcc (or whatever you use) will make a pre-compiled version of every file you have.
2) It links all those pre-compiled files into either, an executable, or a library file, etc...
Now that you know this, you can understand how it works:
- At first step, the compiler can only know functions / variables that are present in a single file, but has no idea about the others, so if you call a function that's not in the file ==> he's not happy and generate an "undeclared function" error. But if you provide him with a header file, you basically tell the compiler "don't mind about this function missing, I'll add it later, in another file, at linking time". So the compilers ignores the error.
- At second steps, when linking all files together, it will check once more, that you kept your promise, by giving him an implementation for the functions that were defined in your header files. Otherwise, you get another kind of error, like "could not find function XXX" (my error names aren't accurate, i haven't done C for a year now).
node.js equivalent of python's if __name__ == '__main__'
The docs describe another way to do this which may be the preferred method:
When a file is run directly from Node, require.main is set to its module.
To take advantage of this, check if this module is the main module and, if so, call your main code:
function myMain() {
// main code
}
if (require.main === module) {
myMain();
}
EDIT: If you use this code in a browser, you will get a "Reference error" since "require" is not defined. To prevent this, use:
if (typeof require !== 'undefined' && require.main === module) {
myMain();
}
Inputs and Outputs in Python?
if _ _name_ _ == '_ _main_ _':
This is not valid Python. It'll cause a SyntaxError
.
R, C = map(int, raw_input().split())
This is not correctly indented. Furthermore, raw_input()
will be executed once, which means that it'll only consume one line of user input and then the .split()
will actually split by space characters.
assert 1 <= R <= 20
This is not really needed, as your logic does not have any solid requirement (The assignment is not telling you to disallow high numeric values)
for r in range(R): print('*' * C)
This will do the trick.
As per my comments above, consider the following:
# If Python 2.x
# from __future__ import print_function
def stdin_readline():
# If Python 2.x
# return raw_input()
# If Python 3.x
return input()
if __name__ == '__main__':
R = int(stdin_readline())
C = int(stdin_readline())
for r in range(R):
print('*' * C)
You can reduce this to just three lines:
# If Python 2.x
# from __future__ import print_function
def stdin_readline(*args):
# If Python 2.x
# return raw_input()
# If Python 3.x
return input()
if __name__ == '__main__':
R, C = map(int, map(stdin_readline, range(2)))
output = map(print, ['*' * C for r in range(R)])
# If Python 3.x
list(output)
RuntimeError on windows trying python multiprocessing
On Windows the subprocesses will import (i.e. execute) the main module at start. You need to insert an if __name__ == '__main__':
guard in the main module to avoid creating subprocesses recursively.
Modified testMain.py
:
import parallelTestModule
if __name__ == '__main__':
extractor = parallelTestModule.ParallelExtractor()
extractor.runInParallel(numProcesses=2, numThreads=4)
Why do I keep getting this big error in python. Traceback (most recent call last)..... and AttributeError
Your init()
call in main.py
needs to be in an if __name__ == '__main__':
block, and you should not set __name__
yourself - Python will do that automatically.
Otherwise your circular imports will cause helper
to not be imported properly before init()
is called. The sequence as it stands is going like this:
- You run main.py, which starts main.py being evaluated.
- The
import helper
line in main.py starts helper.py being evaluated. - The
import main
line in helper.py starts another evaluation of main.py because themain
module has not been previously imported. - The
import helper
line in the second evaluation of main.py imports the existing helper object that was created when #2 started helper being imported, so this doesn't create an infinite loop - but the existing helper object hasn't fully loaded yet; it's still waiting for themain
import to resolve. - The second evaluation of
main
hits theinit()
call at the bottom of main.py, which tries to runinit()
- buthelper
still isn't done loading, and thus theway_out_quest
function in helper.py hasn't been evaluated yet and thus is not defined.
In general, it's best to avoid circular imports in the first place - then you don't have to worry about problems like this.
Related Topics
Calling the "Source" Command from Subprocess.Popen
How to Generate an HTML Directory List Using Python
Plotting 3-Tuple Data Points in a Surface/Contour Plot Using Matplotlib
How to Use Rpy2 to Save a Pandas Dataframe to an .Rdata File
Expand Python Search Path to Other Source
Differencebetween List and List[:] in Python
A Mutable Type Inside an Immutable Container
Using a Pre-Trained Word Embedding (Word2Vec or Glove) in Tensorflow
Driving Excel from Python in Windows
In Python, How to Import Filename Starts with a Number
Opencv Videocapture and Error: (-215:Assertion Failed) !_Src.Empty() in Function 'Cv::Cvtcolor'
Understand the Find() Function in Beautiful Soup
R Markdown: How to Make Rstudio Display Python Plots Inline Instead of in New Window
Python 3.7 Anaconda Environment - Import _Ssl Dll Load Fail Error