if __name__ == '__main__' not working ipython - python

I'm having trouble getting the if __name == '__main__' trick to work in an IPython, Spyder environment. I've tried every approach given in this thread:
if __name__ == '__main__' in IPython
Here are my super simplified modules
Module1.py
Class UnitTest():
print 'Mod1 UnitTest!'
if __name__ == '__main__':
UnitTest()
Module2.py
import Module1
Class UnitTest():
print 'Mod2 UnitTest!'
if __name__ == '__main__':
UnitTest()
So I run Module2.py and I always am seeing both Mod2 UnitTest and Mod1 UnitTest printed. These are executing in an IPython kernel. I want only the Mod2 UnitTest message to display.
Any idea what's up?

Well I deleted this question earlier out of embarrassment but might as well share in case any other newb sees this.
I forgot to put the UnitTest line inside of the __init__ method. So the unit test was being run every single time when the class was defined and not when the object was instantiated. The code should be:
Module1.py
Class UnitTest():
def __init__(self):
print 'Mod1 UnitTest!'
if __name__ == '__main__':
UnitTest()
Module2.py
import Module1
Class UnitTest():
def __init__(self):
print 'Mod1 UnitTest!'
if __name__ == '__main__':
print 'Mod2 UnitTest!'

Related

Why do so many people put the app.run() in flask sites into a __name__ == "__main__" condition?

I know what if __name__ == "__main__" does and use it, but why do so many people and the documentation put the " app.run() " function of flask in this condition?
This is because there are certain situation where you have to access certain variables for example when you have a sqlalchemy database and If you want create tables. You have to do
from app import db
In such situation you app will run
Also when you move to production you don't need run and app is called from elsewhere if you add if __name__ == "__main__" part run will not be called unnecessarly.
This will ensure that when this module is imported, it won't run the code within
if __name__ == "__main__":
Your name == "main" when you run the .py directly.
ex:
foo.py
import bar
print("This is foo file)
now the inverse:
bar.py
import foo
def main():
print(This is bar file)
print(__name__)
if __name__ == "__main__":
main()
(running the bar.py file)
python bar.py
This is foo file
This is bar file
"__main__"
(running the foo.py file)
python foo.py
this is foo file
I know others will comment and provide a more thorough answer. But this is one way of looking at it.
Cheers.

Displaying an object atributes in pycharm

The pycharm doesn t displaying the prints
PyCharm doesn't display the atribute values of my class
You are missing: if __name__ == '__main__':
Suppose your code is in test.py file:
class P:
def __init__(self, attr):
self.a = attr
p = P(4)
if __name__ == '__main__':
print(p.a)
Run it using python test.py or via PyCharm and you will see 4 in output.
Reason:
When you execute your Python script, Python interpreter sets the variable __name__ to '__main__', the condition __name__ == '__main__' evaluates to True and print function is executed.
When you import test.py as a module in another module, the interpreter sets __name__ to test and the print function call won't be executed.
Refer to What does if name == “main”: do? for more details.

The difference between __main__ and launch() methods

I'm still in the learning phase and I have this question.
So in order to execute a class, we use if __name__ == '__main__': and call the class as the following
class Example():
def test(self):
print "Hello There"
if __name__ == '__main__':
Example()
However, I saw some classes that use def launch(): instead of if __name__ == '__main__':, so the question here: Are they similar so I can both ways or def launch(): has a special propose?
Thank you.
Python runs anything in the top level this is why we use classes and functions to separate jobs (among other reasons).
So for example here
Script a.py
def main():
pass
main()
The interpreter will define a function called main() but when it reaches the main() call in the top level (aligned left most)
it will execute the main function.
Now in the case of your launch()
if __name__ == '__main__':
Example()
vs
__name__ = __main__
This is used in the case where someone wants to import a program or class but doesn't want it to run when the interpreter runs into it.
Import a will call the main() at that point and time
however let's say b.py is structurally similar but instead of main() it has __name__ = __main__, b.py won't run unless directly called.
The reason I bring this is up is because as #harshil9968 pointed out, Python has no "launch" method. What likely was happening is they defined a launch() method instead of main()
Then put it under a class
class A():
def launch(self):
#actions
if __name__ == '__main__':
A()
Call to A() calls the launch() method within the A class.

Python Define Unit Test Classes Together with Code

I am rapid prototyping so for now I would like to write unit tests together with the code I am testing - rather than putting the tests in a separate file. However, I would only like to build the test an invoke them if we run the code in the containing file as main. As follows:
class MyClass:
def __init(self)__:
# do init stuff here
def myclassFunction():
# do something
if __name__ == '__main__':
import unittest
class TestMyClass(unittest.TestCase):
def test_one(self):
# test myclassFunction()
suite = unittest.TestLoader().loadTestsFromTestCase(TestMyClass)
unittest.TextTestRunner(verbosity=2).run(suite)
This of course doesn't run as unittest is unable to find or make use of the test class, TestMyClass. Is there a way to get this arrangement to work or do I have to pull everything out of the if __name__ == '__main__' scope except the invocation to unittest?
Thanks!
If you move your TestMyClass above of if __name__ == '__main__'
you will get exactly what you want:
Tests will run only when file executed as main
Something like this
import unittest
class MyClass:
def __init(self)__:
# do init stuff here
def myclassFunction():
# do something
class TestMyClass(unittest.TestCase):
def test_one(self):
if __name__ == '__main__':
unittest.main()

Mocking __main__

I would like to ensure with tests that:
- the application cannot be imported
- the application can be started as a real application (i.e: python src.py)
I'm interested about that, why the following is not working:
src.py
class A:
def x(self):
print('this is x')
if __name__ == '__main__':
A().x()
test.py (snippet)
class Test(unittest.TestCase):
#mock.patch('src.A.x')
def test_main(self, mock_x):
import src
mock_x.assert_any_call()
This test fails... why?
Because the name of the module when imported is src, not __main__.
The easiest solution would be to move that code into a function:
def main():
A().x()
if __name__ == '__main__':
main()
and in your test, you would invoke src.main()
#mock.patch('src.A.x')
def test_main(self, mock_x):
import src
src.main()
mock_x.assert_any_call()
To test that a module is not importable you do not need to use mocks.
See assertRaises.
Just check if an error is thrown on import od module.
with self.assertRaises(...):
...

Categories

Resources