I'm creating a virtual OS with different files, like boot.py and Run.py
It worked for a while until I typed this in:
if Run.run == 0:
error()
else:
start()
There is no errors saying about it like red lines or any. Now I get this error:
AttributeError("module 'boot' has no attribute 'bootup'",)
Here's the code:
boot.py:
#Imports
import Run
#Varibles
name = "PyOS"
version = 1
creator = "© Dragon Softwares"
def bootup(run):
if Run.run == 0:
error()
else:
start()
def start():
print("Starting PyOS")
print("Version ", version)
def error():
print("Please Run 'Run.py' To bootup the system")
bootup()
Run.py:
#Imports
import time
import boot
#Varibles
run = 0
def main():
run = 1
time.sleep(0.1)
boot.bootup
main()
You have a circular import. Don't have boot import Run and vice-versa.
What happens now is:
Run.py is executed as the __main__ module.
The line import boot is reached and executed.
boot has not been imported before, so boot.py is found and loaded to be the boot module.
The line import Run is reached and executed.
Run has not been imported before, so Run.py is found and loaded to be the Run module. Note: that Run.py is also used for __main__ does not matter here.
The line import boot is reached and executed.
boot is already being imported, so it used to set the name boot in the Run module
Various other names are set in the Run module namespace (run and main).
The line main() is reached and executed
The main() function references boot.bootup, which doesn't exist yet, because the boot module top-level code never reached the def bootup(run): line.
Instead of importing Run, pass the run value as a parameter to the boot function:
def main():
run = 1
time.sleep(0.1)
boot.bootup(run)
Also, don't call bootup() at the end of the boot module. That function call will be executed when you import boot, and makes no sense there. If you want to present an error message, use a if __name__ == '__main__': guard:
if __name__ == '__main__':
import sys
error()
sys.exit(1)
The if test will only ever be true if you ran boot.py as the script.
Related
I'm relatively new to python so please forgive early level understanding!
I am working to create a kind of flag file. Its job is to monitor a Python executable, the flag file is constantly running and prints "Start" when the executable started, "Running" while it runs and "Stop" when its stopped or crashed, if a crash occurs i want it to be able to restart the script. so far i have this down for the Restart:
from subprocess import run
from time import sleep
# Path and name to the script you are trying to start
file_path = "py"
restart_timer = 2
def start_script():
try:
# Make sure 'python' command is available
run("python "+file_path, check=True)
except:
# Script crashed, lets restart it!
handle_crash()
def handle_crash():
sleep(restart_timer) # Restarts the script after 2 seconds
start_script()
start_script()
how can i implement this along with a flag file?
Not sure what you mean with "flag", but this minimally achieves what you want.
Main file main.py:
import subprocess
import sys
from time import sleep
restart_timer = 2
file_path = 'sub.py' # file name of the other process
def start():
try:
# sys.executable -> same python executable
subprocess.run([sys.executable, file_path], check=True)
except subprocess.CalledProcessError:
sleep(restart_timer)
return True
else:
return False
def main():
print("starting...")
monitor = True
while monitor:
monitor = start()
if __name__ == '__main__':
main()
Then the process that gets spawned, called sub.py:
from time import sleep
sleep(1)
print("doing stuff...")
# comment out to see change
raise ValueError("sub.py is throwing error...")
Put those files into the same directory and run it with python main.py
You can comment out the throwing of the random error to see the main script terminate normally.
On a larger note, this example is not saying it is a good way to achieve the quality you need...
I am trying to package my python project into an executable using pyinstaller. The main module contains code for multiprocessing. When I run the executable, only the lines of code prior to the multi processing part get executed again and again. Neither does it throw an exception or exit the program.
Code in main module:
from Framework.ExcelUtility import ExcelUtility
from Framework.TestRunner import TestRunner
import concurrent.futures
class Initiator:
def __init__(self):
self.exec_config_dict = {}
self.test_list = []
self.test_names = []
self.current_test_set = []
def set_first_execution_order(self):
# Code
def set_subsequent_execution_order(self):
# Code
def kick_off_tests(self):
'''Method to do Multi process execution'''
if(__name__=="__main__"):
with concurrent.futures.ProcessPoolExecutor(max_workers=int(self.exec_config_dict.get('Parallel'))) as executor:
for test in self.current_test_set:
executor.submit(TestRunner().runner,test) ***This line is not being executed from the exe file.
initiator = Initiator()
initiator.get_run_info()
initiator.set_first_execution_order()
initiator.kick_off_tests()
while len(initiator.test_list) > 0:
initiator.set_subsequent_execution_order()
try:
initiator.kick_off_tests()
except BaseException as exception:
print(exception)
From the problem definition I'm assuming you are using ms-windows, and that the main module is not named __main__.py.
In that case, multiprocessing has some special guidelines:
Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects (such a starting a new process).
and
Instead one should protect the “entry point” of the program by using if __name__ == '__main__'
So, change the last part of your main module like this:
from multiprocessing import freeze_support
def kick_off_tests(self):
'''Method to do Multi process execution'''
with concurrent.futures.ProcessPoolExecutor(max_workers=int(self.exec_config_dict.get('Parallel'))) as executor:
for test in self.current_test_set:
executor.submit(TestRunner().runner,test)
if __name__ == '__main__':
freeze_support()
initiator = Initiator()
initiator.get_run_info()
initiator.set_first_execution_order()
initiator.kick_off_tests()
while len(initiator.test_list) > 0:
initiator.set_subsequent_execution_order()
try:
initiator.kick_off_tests()
except BaseException as exception:
print(exception)
I want to use my project's new lib file. However, i don't hope to main progress stop running?
for example ,i have b.py:
import a
import time
def main():
for i in range(1000):
time.sleep(5)
print i
a.abc()
main()
a.py is
def abc():
print 'abc'
I want to modify my abc function in a.py to
def abc():
print '123'
When i finish modified abc function in a.py, I hope it worked at once in main process in a.py .
i remove a.pyc file, but it still print abc, not 123. How to print 123 when don't stop main progress?
Can't change main process. Because it is always running.
You might want to save your module hashsum and after every execution check if it changed and reload if so:
import hashlib
import time
import a
def main():
with open('a.py', 'rb') as f:
module_hashsum = hashlib.md5(f.read()).hexdigest()
for i in range(1000):
time.sleep(5)
print i
a.abc()
with open('a.py', 'rb') as f:
hashsum_temp = hashlib.md5(f.read()).hexdigest()
if module_hashsum != hashsum_temp:
module_hashsum = hashsum_temp
reload(a)
main()
Or just reload it after every execution.
Might aswell do some fancy checks for file's mtime, like it's done in django. But it will trigger reload even if you didn't change anything in a file and only did :wq in Vim (just saved file) for e.g.
But I don't think it's necessary, as building hash is fast.
By starting the main, I´m starting a thread that keeps a connection to a opcua server alive (and a few things more).
I now want to open a function inside this thread but I don´t want to import everything again (because it takes to long).
In if __name__ == "__main__":
it is working, but when I run a second script goIntoThread.py, it is not working. Obviously because I didn´t import the modules...
What are my options to trigger e.g. thd.doSomethingInThread() without importing everything again?
Thnaks alot!
main.py
import time
def importOnlyMain():
global KeepConnected
from keepConnected import KeepConnected
if __name__ == "__main__":
importOnlyMain()
global thd
thd = KeepConnected()
thd.start()
time.sleep(3)
thd.doSomethingInThread()
def goIntoThread():
print("Going to Thread")
thd.doSomethingInThread()
goIntoThread.py
import main
main.goIntoThread()
Copy Comment: I get the following error:
thd.setBool()
NameError: global name 'thd' is not defined
I am trying to call a script from python-daemon but its not working. this is what i am tying to do, is it correct?
I also want to pass a random argument to that script, currently i have hard coded it
import daemon
import time
import subprocess
import os
def interval_monitoring():
print "Inside interval monitoring"
while True:
print "its working"
# os.system("XYZ.py 5416ce0eac3d94693cf7dbd8") Tried this too but not working
subprocess.Popen("XYZ.py 5416ce0eac3d94693cf7dbd8", shell=False)
time.sleep(60)
print "condition true"
def run():
print daemon.__file__
with daemon.DaemonContext():
interval_monitoring()
if __name__ == "__main__":
run()
If you didn't make XYZ.py executable and added #!/usr/bin/env python in the top line, you need to call it via python, rather than directly. So your line would be something like this:
subprocess.check_output(["python", "XYZ.py", "5416ce0eac3d94693cf7dbd8"])