निम्न कोड आपको रन समय पर runtime.py
की सामग्री को संशोधित करने की अनुमति देता है। दूसरे शब्दों में, आपको runner.py
को बाधित करने की आवश्यकता नहीं है।पायथन रनिंग प्रोग्राम का हॉट-स्वैपिंग
#runner.py
import time
import imp
def main():
while True:
mod = imp.load_source("runtime", "./runtime.py")
mod.function()
time.sleep(1)
if __name__ == "__main__":
main()
मॉड्यूल कार्यावधि में आयातित है:
# runtime.py
def function():
print("I am version one of runtime.py")
यह आदिम तंत्र की अनुमति देता है आप के लिए "कैसे-स्वैप" अजगर कोड (एक ला Erlang)। क्या कोई बेहतर विकल्प है?
कृपया ध्यान दें कि यह एकमात्र अकादमिक प्रश्न है, क्योंकि मुझे ऐसा कुछ करने की आवश्यकता नहीं है। हालांकि, मुझे पाइथन रनटाइम के बारे में अधिक जानने में दिलचस्पी है।
संपादित:
मैं निम्नलिखित समाधान बनाया: एक Engine
वस्तु (इस मामले मॉड्यूल engine.py
कहा जाता है) में एक मॉड्यूल में निहित कार्यों के लिए एक इंटरफेस प्रदान करता है। Engine
ऑब्जेक्ट भी थ्रेड उत्पन्न करता है जो स्रोत फ़ाइल में परिवर्तनों की निगरानी करता है और यदि परिवर्तनों का पता चला है, तो यह इंजन पर notify()
विधि को कॉल करता है, जो स्रोत फ़ाइल को पुनः लोड करता है।
मेरे कार्यान्वयन में, परिवर्तन पहचान फ़ाइल के SHA1 चेकसम की जांच करने वाले प्रत्येक frequency
सेकंड पर मतदान पर आधारित है, लेकिन अन्य कार्यान्वयन संभव है।
इस उदाहरण में hotswap.log
नामक फ़ाइल में प्रत्येक परिवर्तन का पता चला है, जहां चेकसम पंजीकृत है।
परिवर्तनों का पता लगाने के लिए अन्य तंत्र Monitor
धागे में एक सर्वर या inotify
का उपयोग हो सकता है।
import imp
import time
import hashlib
import threading
import logging
logger = logging.getLogger("")
class MonitorThread(threading.Thread):
def __init__(self, engine, frequency=1):
super(MonitorThread, self).__init__()
self.engine = engine
self.frequency = frequency
# daemonize the thread so that it ends with the master program
self.daemon = True
def run(self):
while True:
with open(self.engine.source, "rb") as fp:
fingerprint = hashlib.sha1(fp.read()).hexdigest()
if not fingerprint == self.engine.fingerprint:
self.engine.notify(fingerprint)
time.sleep(self.frequency)
class Engine(object):
def __init__(self, source):
# store the path to the engine source
self.source = source
# load the module for the first time and create a fingerprint
# for the file
self.mod = imp.load_source("source", self.source)
with open(self.source, "rb") as fp:
self.fingerprint = hashlib.sha1(fp.read()).hexdigest()
# turn on monitoring thread
monitor = MonitorThread(self)
monitor.start()
def notify(self, fingerprint):
logger.info("received notification of fingerprint change ({0})".\
format(fingerprint))
self.fingerprint = fingerprint
self.mod = imp.load_source("source", self.source)
def __getattr__(self, attr):
return getattr(self.mod, attr)
def main():
logging.basicConfig(level=logging.INFO,
filename="hotswap.log")
engine = Engine("engine.py")
# this silly loop is a sample of how the program can be running in
# one thread and the monitoring is performed in another.
while True:
engine.f1()
engine.f2()
time.sleep(1)
if __name__ == "__main__":
main()
engine.py
फ़ाइल:
# this is "engine.py"
def f1():
print("call to f1")
def f2():
print("call to f2")
लॉग नमूना:
INFO:root:received notification of fingerprint change (be1c56097992e2a414e94c98cd6a88d162c96956)
INFO:root:received notification of fingerprint change (dcb434869aa94897529d365803bf2b48be665897)
INFO:root:received notification of fingerprint change (36a0a4b20ee9ca6901842a30aab5eb52796649bd)
INFO:root:received notification of fingerprint change (2e96b05bbb8dbe8716c4dd37b74e9f58c6a925f2)
INFO:root:received notification of fingerprint change (baac96c2d37f169536c8c20fe5935c197425ed40)
INFO:root:received notification of fingerprint change (be1c56097992e2a414e94c98cd6a88d162c96956)
INFO:root:received notification of fingerprint change (dcb434869aa94897529d365803bf2b48be665897)
फिर से - यह एक शैक्षिक चर्चा क्योंकि मैं गर्म गमागमन अजगर के इस समय कोई आवश्यकता नहीं है कोड। हालांकि, मुझे रनटाइम थोड़ा सा समझने में सक्षम होना पसंद है और यह पता है कि क्या संभव है और क्या नहीं है। ध्यान दें कि मॉड्यूल सफलतापूर्वक लोड नहीं होने पर लोडिंग तंत्र लॉक जोड़ सकता है, अगर यह संसाधनों का उपयोग कर रहा है, और अपवाद हैंडलिंग।
टिप्पणियां?
अपने quesiton में एक उत्तर संपादित न करें। इसे एक उत्तर के रूप में जोड़ें। – agf
संभावित डुप्लिकेट [मैं एक पायथन मॉड्यूल को अनलोड (पुनः लोड) कैसे करूं?] (Http://stackoverflow.com/questions/437589/how-do-i-unload-reload-a-python-module) –