I am trying to restart my main.py after the program has finished running. However, when I go into the last file (unlock.py) then put at the end of the script:
from main import *
main()
I get a circular import error. I am not sure a way to work around this so if anyone knows, your help would be greatly appreciated. If you have any questions, feel free to ask.
You can use the execv method of os module:
import os
import sys
os.execv(__file__, sys.argv)
If you're getting any permission errors:
os.execv(sys.executable,
[sys.executable, os.path.join(sys.path[0], __file__)] + sys.argv[1:])
To disable warnings:
import warnings
warnings.filterwarnings("ignore")
Without seeing the structure of your program, the best recommendation I can give is to pass your main function around as an argument. That way, in unlock.py, you don't need to import the main module.
Consider this simple example:
main.py
import unlock
def main(function_to_pass):
# do stuff
unlock.some_func(function_to_pass,*rest_of_args)
if __name__ == '__main__':
main(main)
unlock.py
def some_func(function_to_call,*args):
# do stuff
if some_condition:
function_to_call()
EDIT: I realized that you don't need to pass main into itself. main can simply reference itself. That is,
def main():
# do stuff
unlock.some_func(main,*args)
Related
On the following path:
main
system.py
|-----pid
init.py
pid.py
tunning_methods.py
pid.py has the following relevant import lines:
import tunning_methods
tunning_methods.py does not import any other file as it does not need it.
init.py is empty, and system.py has the following import lines:
import pid.tunning_methods
import pid.pid
every file has a function to test it on the format:
if __name__ == "__main__":
testfunc()
now when i try to run pid.py it runs just fine, however when i try to run system.py it raises an error saying the is no such module named tunning_methods.py on the pid.py file. I was able to solve that by importing "import pid.tunning_methods" on the pid.py it was like on the system vision of import path, instead of the pid, however the pid now does not run, more than that im having a lot of trouble with imports, this is just a piece of application that goes in to a much bigger one, its possible to do this for every import, however i want an easier solution, any ideas ?
tried to do the imports on the description and it did not work as i was intending.
for anyone having the same problem the suggestion that Michael gave worked, a relative import from . import tunning_methods.
I want to implement certain functionality using python that can be used in two ways:
as simple command line script, like python mylib.py
by importing into other python code
My first attempts look like this.
mylib.py:
from __future__ import print_function
import sys
class A(object):
def __init__(self, args):
print("my args: {}".format(args))
def main():
a = A(sys.argv)
print("got {}".format(a))
main()
Which I can directly invoke, or use elsewhere, like usage.py:
import mylib
mylib.A("bla")
That works, but it seems the import causes main() to be executed as well:
python scripts/using.py blub
my args: ['scripts/using.py', 'blub']
got <mylib.A object at 0x7ff17bc736d0>
my args: bla
Questions:
Is there a way to prevent main() from running when I go for python using.pl?
And beyond that:
Is this a good approach? Or are there well established best practices in python that I am violating here?
In other words: are there things I should do differently?
This is why you add
if __name__ == '__main__':
main()
If this .py file is directly invoked, your main will run. If your file is simply imported, it will not run main. See here
Since #CoryKramer has already answered the first part of the question, let me take a shot at the second part.
Code should exists where it belongs. If it has anything to do with parsing the script or the main execution, then it should be in the script. Any other piece of code shouldn't be the part of script file.
Generally, in production code, you should never import from a script file. The common code should exist in it's own class in a separate file or just in a separate file in case of procedural approach. This way the code in your script would be succinct and the code in the common file is reusable in other production code and you won't run a risk of accidentally executing a script, just to use the common code.
# common.py
class A(object):
def __init__(self, args):
print("my args: {}".format(args))
# mylib.py
from common import A
if __name__ == '__main__':
a = A(sys.argv)
print("got {}".format(a))
I'm using python 2.7, the following is the simplified version of my script:
executor.py
import sys
def someCal(num):
num = int(num)
print num*num
someCal(sys.argv[1])
so python executor.py 13 would print out 169, it's working as expected.
and I have another script, I want to make use of someCal() function in executor.py so I import it
main.py
import executor
to_count = 999
executor.someCal(to_count)
I got the error message below when execute python main.py:
File "main.py", line 3, in <module>
import executor
File "/Users/mac/executor.py", line 13, in <module>
someCal(sys.argv[1])
I don't know why it keep mentioning about line 13 in executor.py, because I didn't use that part.
Thanks in advance!
from executor import *
It is a better method and will work fine as you wanted.No need if name == 'main': with this method. Also you can call your functions with their names.Like:
from executor import *
print (someCal(10))
Edit for example:
executor.py
def someCal(num):
num = int(num)
return num*num
another.py
from executor import *
print (someCal(10))
Output:
>>>
100
>>>
If you working with functions, you should return a value in function, not print. If you return a value, you can print it later.But if you dont use return and just keep it like print num*num, then you cant use it later with print function. You can try and see that.So, returning a value is important in functions.
For your second question, check this one: What does if __name__ == "__main__": do?
Python is the best language about clear codes, so you should keep it clear, sys is not necessary for you. And you dont need if name == 'main': this statement, remember every .py file is a module, so if you can import any module without that statement,like import random; then you can import your own modules too.Just care about they have to stay in same directory so Python can find your own module/file. Keep it simple :-)
Another import method for a module is:
import executor as ChuckNorris
print (ChuckNorris.someCal(10))
Output is same of course, you can write whatever you want instead of ChuckNorris, but be sure that name doesnt overlap with another function name in your program. For example you have a .py file called Number.py, you will import this file to another file, but you cant be sure is there any function called Number in another one, so you can call it like import Number as whatyouwanttocallit and you will avoid from that problems.
When you import executor in main.py, it actually doing python executor.py, I suggest you change your executor.py to:
if __name__ == '__main__':
someCal(sys.argv[1])
and, you might want to add defensive code like if len(sys.argv)>1 before use sys.argv[1] directly
... could someone explain the difference?
What I type in the command prompt:
sys.path.append('M:/PythonMods')
import qrcode
myqr = qrcode.make("randomtexxxxxxxxxt")
myqr.show()
myqr.save("M:/myqr.png")
MAKES A QR FOR THE TEXT.
The code I type:
sys.path.append('M:/PythonMods')
import scipy
from qrcode import myqr
file=open('myqr3.png',"r")
myqr.show()
file.close()
It doesn't recognise sys, do I need to import something? How come it runs in the command prompt?
Thanks in advance for any help.
add at the begining of your source file:
import sys
and while we're reviewing your code, in executable source files it is advised to do so:
import sys
sys.path.append('M:/PythonMods')
import qrcode
if __name__ == "__main__":
myqr = qrcode.make("randomtexxxxxxxxxt")
myqr.show()
myqr.save("M:/myqr.png")
so your code will run only when you execute it as a file, not when you import it. You may want to define your three lines as a function, and call your function in the if __name__ == "__main__": part, to be able to reuse it like any library!
At the top of the script, please include the following line:
import sys
sys is not a built-in, you do need to explicitly import it:
import sys
The ipython interactive shell imports a lot of modules by default; perhaps you are using that to test your code. The default Python runtime does not import sys for you.
I have a module that has the usual
if __name__ == '__main__':
do stuff...
idiom.
I'd like to import that from another module, and fool it into running that code. Is there any way of doing this?
I should mention, for reasons I won't go into here, I'm not in a position to change the code in the imported module. I need to somehow modify the import procedure so that it's name is main when imported, perhaps using ihooks or similar.
As pointed out in the other answers, this is a bad idea, and you should solve the issue some other way.
Regardless, the way Python does it is like this:
import runpy
result = runpy._run_module_as_main("your.module.name"))
There is, execute the script instead of importing it. But I consider this an extremely hackish solution.
However the ideal pattern would be:
def do_stuff():
... stuff happens ...
if __name__ == '__main__':
do_stuff()
that way you can do:
from mymodule import do_stuff
do_stuff()
EDIT: Answer after clarification on not being able to edit the module code.
I would never recommend this in any production code, this is a "use at own risk" solution.
import mymodule
with open(os.path.splitext(mymodule.__file__)[0] + ".py") as fh:
exec fh.read()
Put that code in a function, and call it from the module you are importing it into as well.
def stuff():
...
if __name__ == '__main__':
stuff()
And then in the module you are importing it into:
import module
module.stuff()
The correct answer has been already given however it is confined in a comments (see How to import a module as __main__?
and How to import a module as __main__?).
The same with proper formatting:
import runpy
runpy.run_module("your.module.name", {}, "__main__")
or
import runpy
runpy.run_path("path/to/my/file.py", {}, "__main__")
Code in a main stanza usually never makes sense to run directly. If you want to run it then use subprocess to run it in another Python interpreter.
Here is an example of a main module in Python:
#! /usr/bin/env python
import sys
import os
def main(arg1, arg2, arg3):
print(arg1, arg2, arg3)
if __name__ == "__main__":
main(*sys.argv)
But you can also include
def main():
#The module contains Python code specific to the library module,
#like tests, and follow the module with this:
if __name__ == "__main__":
main(*sys.argv)
in any module you would like to run as main.
For example, if you have a library module, you can always use this construct to execute something specific like tests.
Put it in a function:
def _main():
do stuff
if __name__ == '__main__':
main()