Exit from imported script in python - python

abc.py:
import xyz
#also import other required modules
#other required code
xyz.func()
#other required code
xyz.py:
import threading
import sys
#few threads
def func():
#start all threads
threads.start()
threads.join(timeout)
#if not joined within given time, terminate all threads and exit from xyz.py
if (threads.isAlive()):
sys.exit()
#I used sys.exit() but it is not working for me.What else can I do here? `
I have a python script abc.py that imports another python script xyz.py.
I am using sys.exit() function in xyz.py. Problem I am facing here is when sys.exit() function is executed in xyz.py file, my main file i.e. abc.py also gets terminated. I don't want this to happen. My file abc.py should remain ON even though xyz.py file terminates. Is there any way to achieve this? I will be grateful to receive any help/guidance.I am using python 2.6.6 on centos 6.5.

The problem that xyz.py is in a same type is module and script. There is common construct if __name__ == '__main__' that allow to separate script part in xyz.py from module part. More information here: What does if __name__ == “__main__”: do?
Also, you misunderstanding how import works. There is no such thing as termination of abc.py or xyz.py, there is single interpreter which maintains global namespace containing abc.py objects. When interpreter meets import xyz statement it simply adds name xyz to namespace and to build its content, it interprets statements in that file. When it meets sys.exit(0) it executes it thus exiting interpreter itself.
May be you need to keep both files as a scripts and keep interpreters separate? Then instead of importing, use subprocess.call, i.e:
import subprocess
subprocess.call([sys.executable, 'xyz.py'])

Related

How do I get two modules to run after each other?

I'm trying to import two modules so that they run after each other. Here is my code:
from Game import *
main()
from Typing_Question_Screen import *
When I run my code, the Game module loads first but if I close the file, the Typing_Question_Screen module is loaded too. But once the Game module finishes, nothing loads next.
How can I run these two right after each other so that when the Game file ends, the Typing_Question_Screen loads too? Thank you.
From my understanding you have two files:
file1.py
file2.py
If you want to run file.1py and then run file2.py without having to manually do it, there are multiple ways. I would recommend creating a batch.
So you have your two .py files. You will want to create a new file. Don't worry about the extension. We will take care of that later. Navigate to your terminal at the bottom and type in where python. That is the first thing you will put in the double quotes. The next is where your file1.py file is located. You will do the same for file2.py indicated in picture 5. You can use the pause function to pause the process. So after file1.py and ran you will be promted to start file2.py. If you don't want to be prompted, then just remove the pause. You then need to navigate to your file explore to where the batch file was created. In my case it is here (picture 6). Right click on the batch file and select rename. Add .bat at the end. That will convert it to the batch file. Then when you run it (doubleclick). The two .py files that we set up in the batch will run!
The statements in the global scope of imported modules are executed when they are imported. So, you may consider adding function calls or other desired statements in the global scope. Let me give an example:
Game.py:
def main():
print("game")
main()
Typing_Question_Screen.py:
def test():
print("tqs")
test()
The importing file:
from Game import *
from Typing_Question_Screen import *
print("import complete")
The output of this file would be:
game
tqs
import complete
Note that you can check whether the module is being executed independently. (Please keep in mind that usually the opposite of this behavior is used, and generally imports are not expected to execute code by themselves.)
For example, the below implementation calls main only if the module is being imported:
def test():
print("tqs")
if __name__ != __main__:
test()
__name__, a special variable of the module set by the interpreter, is __main__ when the module is run without being imported.
Also, I would avoid importing with *. Moreover, the imports should be at the top of the importing file, separated from other statements and definitions. See: PEP8 on importing
I think you may modify your code as:
import Game
import Typing_Question_Screen
Game.main()

Whenever I import a module into my code the entire module is run [duplicate]

I have a Python program I'm building that can be run in either of 2 ways: the first is to call python main.py which prompts the user for input in a friendly manner and then runs the user input through the program. The other way is to call python batch.py -file- which will pass over all the friendly input gathering and run an entire file's worth of input through the program in a single go.
The problem is that when I run batch.py, it imports some variables/methods/etc from main.py, and when it runs this code:
import main
at the first line of the program, it immediately errors because it tries to run the code in main.py.
How can I stop Python from running the code contained in the main module which I'm importing?
Because this is just how Python works - keywords such as class and def are not declarations. Instead, they are real live statements which are executed. If they were not executed your module would be empty.
The idiomatic approach is:
# stuff to run always here such as class/def
def main():
pass
if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()
It does require source control over the module being imported, however.
Due to the way Python works, it is necessary for it to run your modules when it imports them.
To prevent code in the module from being executed when imported, but only when run directly, you can guard it with this if:
if __name__ == "__main__":
# this won't be run when imported
You may want to put this code in a main() method, so that you can either execute the file directly, or import the module and call the main(). For example, assume this is in the file foo.py.
def main():
print "Hello World"
if __name__ == "__main__":
main()
This program can be run either by going python foo.py, or from another Python script:
import foo
...
foo.main()
Use the if __name__ == '__main__' idiom -- __name__ is a special variable whose value is '__main__' if the module is being run as a script, and the module name if it's imported. So you'd do something like
# imports
# class/function definitions
if __name__ == '__main__':
# code here will only run when you invoke 'python main.py'
Unfortunately, you don't. That is part of how the import syntax works and it is important that it does so -- remember def is actually something executed, if Python did not execute the import, you'd be, well, stuck without functions.
Since you probably have access to the file, though, you might be able to look and see what causes the error. It might be possible to modify your environment to prevent the error from happening.
Put the code inside a function and it won't run until you call the function. You should have a main function in your main.py. with the statement:
if __name__ == '__main__':
main()
Then, if you call python main.py the main() function will run. If you import main.py, it will not. Also, you should probably rename main.py to something else for clarity's sake.
There was a Python enhancement proposal PEP 299 which aimed to replace if __name__ == '__main__': idiom with def __main__:, but it was rejected. It's still a good read to know what to keep in mind when using if __name__ = '__main__':.
You may write your "main.py" like this:
#!/usr/bin/env python
__all__=["somevar", "do_something"]
somevar=""
def do_something():
pass #blahblah
if __name__=="__main__":
do_something()
I did a simple test:
#test.py
x = 1
print("1, has it been executed?")
def t1():
print("hello")
print("2, has it been executed?")
def t2():
print("world")
print("3, has it been executed?")
def main():
print("Hello World")
print("4, has it been executed?")
print("5, has it been executed?")
print(x)
# while True:
# t2()
if x == 1:
print("6, has it been executed?")
#test2.py
import test
When executing or running test2.py, the running result:
1, has it been executed?
5, has it been executed?
1
6, has it been executed?
Conclusion: When the imported module does not add if __name__=="__main__":, the current module is run, The code in the imported module that is not in the function is executed sequentially, and the code in the function is not executed when it is not called.
in addition:
def main():
# Put all your code you need to execute directly when this script run directly.
pass
if __name__ == '__main__':
main()
else:
# Put functions you need to be executed only whenever imported
A minor error that could happen (at least it happened to me), especially when distributing python scripts/functions that carry out a complete analysis, was to call the function directly at the end of the function .py file.
The only things a user needed to modify were the input files and parameters.
Doing so when you import you'll get the function running immediately. For proper behavior, you simply need to remove the inside call to the function and reserve it for the real calling file/function/portion of code
Another option is to use a binary environment variable, e.g. lets call it 'run_code'. If run_code = 0 (False) structure main.py to bypass the code (but the temporarily bypassed function will still be imported as a module). Later when you are ready to use the imported function (now a module) set the environment variable run_code = 1 (True). Use the os.environ command to set and retrieve the binary variable, but be sure to convert it to an integer when retrieving (or restructure the if statement to read a string value),
in main.py:
import os
#set environment variable to 0 (False):
os.environ['run_code'] = '0'
def binary_module():
#retrieve environment variable, convert to integer
run_code_val = int(os.environ['run_code'] )
if run_code_val == 0:
print('nope. not doing it.')
if run_code_val == 1:
print('executing code...')
# [do something]
...in whatever script is loading main.py:
import os,main
main.binary_module()
OUTPUT: nope. not doing it.
# now flip the on switch!
os.environ['run_code'] = '1'
main.binary_module()
OUTPUT: executing code...
*Note: The above code presumes main.py and whatever script imports it exist in the same directory.
Although you cannot use import without running the code; there is quite a swift way in which you can input your variables; by using numpy.savez, which stores variables as numpy arrays in a .npz file. Afterwards you can load the variables using numpy.load.
See a full description in the scipy documentation
Please note this is only the case for variables and arrays of variable, and not for methods, etc.
Try just importing the functions needed from main.py? So,
from main import SomeFunction
It could be that you've named a function in batch.py the same as one in main.py, and when you import main.py the program runs the main.py function instead of the batch.py function; doing the above should fix that. I hope.

Why does "from _ import _" run and access all of "from" [duplicate]

I have a Python program I'm building that can be run in either of 2 ways: the first is to call python main.py which prompts the user for input in a friendly manner and then runs the user input through the program. The other way is to call python batch.py -file- which will pass over all the friendly input gathering and run an entire file's worth of input through the program in a single go.
The problem is that when I run batch.py, it imports some variables/methods/etc from main.py, and when it runs this code:
import main
at the first line of the program, it immediately errors because it tries to run the code in main.py.
How can I stop Python from running the code contained in the main module which I'm importing?
Because this is just how Python works - keywords such as class and def are not declarations. Instead, they are real live statements which are executed. If they were not executed your module would be empty.
The idiomatic approach is:
# stuff to run always here such as class/def
def main():
pass
if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()
It does require source control over the module being imported, however.
Due to the way Python works, it is necessary for it to run your modules when it imports them.
To prevent code in the module from being executed when imported, but only when run directly, you can guard it with this if:
if __name__ == "__main__":
# this won't be run when imported
You may want to put this code in a main() method, so that you can either execute the file directly, or import the module and call the main(). For example, assume this is in the file foo.py.
def main():
print "Hello World"
if __name__ == "__main__":
main()
This program can be run either by going python foo.py, or from another Python script:
import foo
...
foo.main()
Use the if __name__ == '__main__' idiom -- __name__ is a special variable whose value is '__main__' if the module is being run as a script, and the module name if it's imported. So you'd do something like
# imports
# class/function definitions
if __name__ == '__main__':
# code here will only run when you invoke 'python main.py'
Unfortunately, you don't. That is part of how the import syntax works and it is important that it does so -- remember def is actually something executed, if Python did not execute the import, you'd be, well, stuck without functions.
Since you probably have access to the file, though, you might be able to look and see what causes the error. It might be possible to modify your environment to prevent the error from happening.
Put the code inside a function and it won't run until you call the function. You should have a main function in your main.py. with the statement:
if __name__ == '__main__':
main()
Then, if you call python main.py the main() function will run. If you import main.py, it will not. Also, you should probably rename main.py to something else for clarity's sake.
There was a Python enhancement proposal PEP 299 which aimed to replace if __name__ == '__main__': idiom with def __main__:, but it was rejected. It's still a good read to know what to keep in mind when using if __name__ = '__main__':.
You may write your "main.py" like this:
#!/usr/bin/env python
__all__=["somevar", "do_something"]
somevar=""
def do_something():
pass #blahblah
if __name__=="__main__":
do_something()
I did a simple test:
#test.py
x = 1
print("1, has it been executed?")
def t1():
print("hello")
print("2, has it been executed?")
def t2():
print("world")
print("3, has it been executed?")
def main():
print("Hello World")
print("4, has it been executed?")
print("5, has it been executed?")
print(x)
# while True:
# t2()
if x == 1:
print("6, has it been executed?")
#test2.py
import test
When executing or running test2.py, the running result:
1, has it been executed?
5, has it been executed?
1
6, has it been executed?
Conclusion: When the imported module does not add if __name__=="__main__":, the current module is run, The code in the imported module that is not in the function is executed sequentially, and the code in the function is not executed when it is not called.
in addition:
def main():
# Put all your code you need to execute directly when this script run directly.
pass
if __name__ == '__main__':
main()
else:
# Put functions you need to be executed only whenever imported
A minor error that could happen (at least it happened to me), especially when distributing python scripts/functions that carry out a complete analysis, was to call the function directly at the end of the function .py file.
The only things a user needed to modify were the input files and parameters.
Doing so when you import you'll get the function running immediately. For proper behavior, you simply need to remove the inside call to the function and reserve it for the real calling file/function/portion of code
Another option is to use a binary environment variable, e.g. lets call it 'run_code'. If run_code = 0 (False) structure main.py to bypass the code (but the temporarily bypassed function will still be imported as a module). Later when you are ready to use the imported function (now a module) set the environment variable run_code = 1 (True). Use the os.environ command to set and retrieve the binary variable, but be sure to convert it to an integer when retrieving (or restructure the if statement to read a string value),
in main.py:
import os
#set environment variable to 0 (False):
os.environ['run_code'] = '0'
def binary_module():
#retrieve environment variable, convert to integer
run_code_val = int(os.environ['run_code'] )
if run_code_val == 0:
print('nope. not doing it.')
if run_code_val == 1:
print('executing code...')
# [do something]
...in whatever script is loading main.py:
import os,main
main.binary_module()
OUTPUT: nope. not doing it.
# now flip the on switch!
os.environ['run_code'] = '1'
main.binary_module()
OUTPUT: executing code...
*Note: The above code presumes main.py and whatever script imports it exist in the same directory.
Although you cannot use import without running the code; there is quite a swift way in which you can input your variables; by using numpy.savez, which stores variables as numpy arrays in a .npz file. Afterwards you can load the variables using numpy.load.
See a full description in the scipy documentation
Please note this is only the case for variables and arrays of variable, and not for methods, etc.
Try just importing the functions needed from main.py? So,
from main import SomeFunction
It could be that you've named a function in batch.py the same as one in main.py, and when you import main.py the program runs the main.py function instead of the batch.py function; doing the above should fix that. I hope.

basic help to call python from unix

Hi I am pretty new to python so I have been playing around with it. I recently created 2 files for some process I am working on which seems to be working while running python but doing nothing when write python name.py argv at the unix command line. It is probably something basic and I would appreciate some help.
1st file (make_dir.py)
import os
import sys
def main():
directory = sys.argv[1]
if not os.path.exists(directory):
os.makedirs(directory)
at unix terminal I write
python make_dir.py /home/user/Python/Test/
result: Test folder is not created.
the second file has probably the same issue.
2nd file directory.py
import sys
import os
def main():
os.chdir(sys.argv[1])
File = open(sys.argv[2] , 'w')
File.write(sys.argv[3])
File.close()
at unix terminal:
python directory.py /home/user/Python/TEST/ a.log "this is a test"
a.log is not created.
If I got some error messages I probably could figure it out but no messages. Any help is much appreciated.
You're defining a function called main, but never call it. Do:
import os
import sys
def main():
...
if __name__ == '__main__':
main()
See here for more details about this idiom.
You are not actually calling main. Simply adding main() at the end of script would suffice, but usually this idiom is used:
if __name__ == '__main__':
main()
This would call main if the script was executed directly, and not just imported from another module.
See executing modules as scripts
Python is not C and def main is not magic. There is no predefined execution entry point for Python programs. All your code is doing is defining a main function (not running it), so Python defines main and then stops (as you requested).
You must call main() explicitly if you want it to execute. You should use this idiom:
if __name__ == '__main__':
main()
__name__ is a magic variable created at the module level that contains the module's name. If __name__ is '__main__', it means the current module was not imported but was run directly. This idiom allows you to use a Python file as both a module (something you can import--where main() should not automatically run) and as a script (where main() should run automatically).

Modules imported twice. Possible bug in Python interpreter

I've made a rather contrived import scheme in a project of mine and I think I might have discovered a bug in the Python interpreter that causes modules to be imported twice.
Here's how my test project is set up:
/
Launcher.bat — Project is run from here. It launches 'main/__init__.py` using the Python 3.2 executable
main/__init__.py — The __main__ script, the one launched by 'Launcher.bat'
main/foo.py — Contains an empty class
external/__init__.py — A script external to the 'main' project scripts, used to demonstrate the problem
./Launcher.bat
#echo off
C:\Python32\python.exe main\__init__.py
pause
./main/__init__.py
from foo import Foo
print("In 'main', Foo has id:", id(Foo))
# Add the directory from which 'Launcher.bat' was run,
# which is not the same as the './main' directory
# in which this script is located
import sys
sys.path.insert(1, '.')
# This script will try to import class Foo, but in doing so
# will casue the interpreter to import this './main/__init__.py'
# script a second time.
__import__('external')
./main/foo.py
class Foo:
pass
./external/__init__.py
from main.foo import Foo
print("In 'external', Foo has id:", id(Foo))
All of this will print the 'Main script was imported' message twice. If the external script imports any other scripts, those too will be imported twice. I've only tested this on Python 3.2. Is this a bug, or did I make a mistake?
Output of the program is:
In 'main', Foo has id: 12955136
In 'main', Foo has id: 12955136
In 'external', Foo has id: 12957456
Press any key to continue . . .
I don't think it's a bug. You should ask on the python-dev list for a more authoritative answer. You are executing once (when you run the script) and importing once (from external) so the line gets printed twice. It's not importing twice.
However, this is a horrible setup. There are a lot of style violations here. Granted that some are for demonstration purposes only, it's still quite messy.
You shouldn't use a package __init__.py file as a file which should be run. The main entry point should be a script that imports the package.
You shouldn't have an imported module importing the module which imported it. Like you external is doing to main.
The first print is misleading: Since you're not importing, but executing the file at the first time (__name__ == '__main__' holds true), the main modules just gets imported once. Move the start point into a secondary file, or check for __name__ == '__main__'.
By the way, circular import are a bad idea. You should resolve the circular import (by moving foo to a dedicated library). Alternatively, you can make your modules reentrant (i.e. check for the current directory being in sys.path before adding it).

Categories

Resources