I created these three functions in python (pool.py, funcA.py, config.py). My intent is that having two python files I would like the two functions to interact. Specifically, I have the pool.py file which has a while loop inside that simulates an always active process that should be blocked when the funcA.py file is called separately. The config.py file is used to create a global variable and use this variable in both files, with funcA.py I go to modify these variables cmd0 and cmd1 and instead with the file pool.py I repeatedly read these variables and check if they change. If you want to test the operation you can take these files and open two terminals in one run pool.py and in the other, you can run the funcA.py file then you can change the content of the cmd0 and cmd1 variables in the funcA.py file while the pool.py function is still running on the other terminal and you can see that the output of the pool.py file updates immediately.
Now my question is how can I make the contents of the funcA.py file become a function and run it directly as a function and have the same result? That is the one that by launching the new function that is inside the funcA.py file I modify the output of the pool.py function that is running on the other terminal.
config.py
def init():
global cmd0, cmd1
cmd0 = ''
cmd1 = ''
return cmd0, cmd1
pool.py
import os
import time
import sys
import numpy as np
import config
import funcA
from importlib import reload
while True:
funcA = reload(funcA)
print(str(config.cmd0))
print(str(config.cmd1))
if config.cmd0 == 'start':
print('stop')
time.sleep(10)
funcA.py
import os
import sys
import numpy as np
import config
config.cmd0 = 'start'
config.cmd1 = 'u1'
If i understood correctly, the following is working:
pool.py
python
import os
import time
import sys
import numpy as np
import config
import funcA
from importlib import reload
while True:
funcA = reload(funcA)
funcA.change_values("cmd0", "cmd1")
print(str(config.cmd0))
print(str(config.cmd1))
if config.cmd0 == 'start':
print('stop')
time.sleep(10)
funcA.py
import os
import sys
import numpy as np
import config
config.cmd0 = 'start'
config.cmd1 = 'u1'
def change_values(a, b):
config.cmd0 = a
config.cmd1 = b
As you can see, the function change_values is called in the pool.py without any check, then the cmd0 and cmd1 will change immediately.
Related
I am trying to put a few python scripts to scheduled and run in main.py. Those scripts are put in the same folder.
main.py:
import schedule
import time
from test1 import dd
schedule.every(2).seconds.do(dd,fname)
while True:
schedule.run_pending()
time.sleep(1)
test1.py:
def dd(fname):
print('hello' + fname)
dd('Mary')
dd('John')
It run out as those 2 name and name 'fname' is not defined.
How to define the argument at main.py file? If I have more than one def in the script, shall I need to import multiple times in the main.py
and the script that I import at top of main.py, it run once before running the schedule? That mean it will run one while you import it?
You are not defining your fname in main.py so it says name 'fname' is not defined. You are only importing the functions to main.py from test1.py
Here is the modified code:
main.py
import schedule
import time
from test1 import dd
fname="Mary"
schedule.every(2).seconds.do(dd,fname)
while True:
schedule.run_pending()
time.sleep(1)
test1.py
def dd(fname):
print('hello' + fname)
if you want to input more than one string, just simply use a list! Here is the sample code for test1.py:
def dd(fname:list):
for n in fname:
print('hello' + n)
These codes are tested using Python 3.7.7
Your problem is that you are trying to use a function argument as it's own variable. Importing is not the problem here.
Try this:
import schedule
import time
from test1 import dd
schedule.every(2).seconds.do(dd,("Any String",))
while True:
schedule.run_pending()
time.sleep(1)
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.
Need help with how to modify/fix code to allow me to control what is occurring in a process. I have looked around and read I need to either make a global variable which the process can read or use an event function to trigger the process. Problem though is I don't know how to implement them in a class function. I thought that if I followed pyimagesearch code that it would work but it appears that it only works with the threading module and not the multiprocessing module.
import RPi.GPIO as GPIO
from RPI.GPIO import LOW,OUT,HIGH,BCM
import multiprocessing as mp
import time
class TestClass():
def __init__(self,PinOne=22,PinTwo=27):
self.PinOne = PinOne
self.PinTwo = PinTwo
self.RunningSys = True
GPIO.setmode(BCM)
GPIO.setup(PinOne,OUT)
GPIO.output(PinOne,LOW)
GPIO.setup(PinTwo,OUT)
GPIO.output(PinTwo,LOW)
def Testloop(self):
while self.RunningSys:
GPIO.output(PinOne,HIGH)
GPIO.output(PinTwo,HIGH)
time.sleep(1)
GPIO.output(PinOne,LOW)
GPIO.output(PinTwo,LOW)
GPIO.output(PinOne,LOW)
GPIO.output(PinTwo,LOW)
def StopPr(self):
self.RunningSys = False
def MProc(self):
MPGP = mp.process(target=TestClass().Testloop())
MPGP.start()
MPGP.join()
In a separate script
From testfile import TestClass
import time
TestClass().MProc()
time.sleep(4)
TestClass().StopPr()
I'm using Pyinstaller to make an .app bundle on Mac OS X, my app generates a config.ini, the script version worked flawlessly, but when it's an .app, it doesn't work.
I'm using ConfigParser to read and write.
I'm using Pyside for GUI.
It doesn't generate my .ini file, hence it doesn't read or write.
Yes, it's an Anime Notifier, got sick of checking it every time.
Code:
import sys
import urllib2
import ConfigParser
import re
import time
import thread
import atexit
from datetime import date
import lxml.html as lx
from PySide.QtCore import *
from PySide.QtGui import *
from pync import Notifier
def layout_widgets(self, layout):
return (layout.itemAt(i) for i in range(layout.count()))
def notify(self):
while True:
config.read('animeConfig.ini')
for newAnime in animeNotify.xpath('//*[#id="frontpage_left_col"]//*[#class="blue"]/text()'):
if config.has_section(newAnime):
for newEp in animeNotify.xpath('//*[#id="frontpage_left_col"]//*[text()="'+newAnime+'"]/parent::h2/following-sibling::h3/a/text()'):
if not config.has_option(newAnime, newEp):
Notifier.notify(newEp+' has been uploaded!', title=newAnime+' '+newEp.lower(), open='http://www.animeseason.com' +
animeNotify.xpath('//*[#id="frontpage_left_col"]//*[text()="'+newEp+'"]/#href')[0])
m = re.findall('\d+', newEp)
config.set(newAnime, newEp, int(m[0]))
with open('animeConfig.ini', 'wb') as configFile:
config.write(configFile)
time.sleep(300)
def checkChecked(self):
while True:
config.read('animeConfig.ini')
for checkbox in self.layout_widgets(self.vLayout):
if checkbox.widget().isChecked() and not config.has_section(checkbox.widget().text()):
config.add_section(checkbox.widget().text())
for anime in animeList.xpath('//*[#class="series_alpha"]/li/span/preceding-sibling::a/text()'):
if config.has_section(anime):
self.EUrl = animeList.xpath('//*[#class="series_alpha"]/li/*[text()="'+anime+'"]/#href')[0]
self.EUrl = lx.parse(urllib2.urlopen("http://www.animeseason.com" + self.EUrl))
for ep in self.EUrl.xpath('//tr/*[#class="text_center"]/a/text()'):
config.set(anime, 'episode '+ep, ep)
with open('animeConfig.ini', 'wb') as configFile:
config.write(configFile)
elif not checkbox.widget().isChecked() and config.has_section(checkbox.widget().text()):
config.remove_section(checkbox.widget().text())
with open('animeConfig.ini', 'wb') as configFile:
config.write(configFile)
time.sleep(300)
I'm also using the thread module so they can operate simultaneously.
Just like so:
thread.start_new_thread(self.notify, ())
thread.start_new_thread(self.checkChecked, ())
Left out the GUI part, because that isn't very interesting, I guess.
I'm using Python 2.7.6 and I have two scripts:
outer.py
import sys
import os
print "Outer file launching..."
os.system('inner.py')
calling inner.py:
import sys
import os
print "[CALLER GOES HERE]"
I want the second script (inner.py) to print the name of the caller script (outer.py).
I can't pass to inner.py a parameter with the name of the first script because I have tons of called/caller scripts and I can't refactor all the code.
Any idea?
One idea is to use psutil.
#!env/bin/python
import psutil
me = psutil.Process()
parent = psutil.Process(me.ppid())
grandparent = psutil.Process(parent.ppid())
print grandparent.cmdline()
This is ofcourse dependant of how you start outer.py.
This solution is os independant.
On linux you can get the process id and then the caller name like so.
p1.py
import os
os.system('python p2.py')
p2.py
import os
pid = os.getppid()
cmd = open('/proc/%d/cmdline' % (pid,)).read()
caller = ' '.join(cmd.split(' ')[1:])
print caller
running python p1.py will yield p1.py
I imagine you can do similar things in other OS as well.
Another, a slightly shorter version for unix only
import os
parent = os.system('readlink -f /proc/%d/exe' % os.getppid())
If applicable to your situation you could also simply pass an argument that lets inner.py differentiate:
import sys
import os
print "Outer file launching..."
os.system('inner.py launcher')
innter.py
import sys
import os
try:
if sys.argv[0] == 'launcher':
print 'outer.py called us'
except:
pass