欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python自動重新加載模塊詳解(autoreload module)

 更新時間:2020年04月01日 10:11:01   作者:promissing  
這篇文章主要介紹了Python自動重新加載模塊詳解(autoreload module),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

守護進程模式

使用python開發(fā)后臺服務程序的時候,每次修改代碼之后都需要重啟服務才能生效比較麻煩。

看了一下Python開源的Web框架(Django、Flask等)都有自己的自動加載模塊功能(autoreload.py),都是通過subprocess模式創(chuàng)建子進程,主進程作為守護進程,子進程中一個線程負責檢測文件是否發(fā)生變化,如果發(fā)生變化則退出,主進程檢查子進程的退出碼(exist code)如果與約定的退出碼一致,則重新啟動一個子進程繼續(xù)工作。

自動重新加載模塊代碼如下:

autoreload.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""This module is used to test how to reload the modules automatically when any
changes is detected.
"""
__author__="Wenjun Xiao"

import os,sys,time,subprocess,thread

def iter_module_files():
 for module in sys.modules.values():
  filename = getattr(module, '__file__', None)
  if filename:
   if filename[-4:] in ('.pyo', '.pyc'):
    filename = filename[:-1]
   yield filename

def is_any_file_changed(mtimes):
 for filename in iter_module_files():
  try:
   mtime = os.stat(filename).st_mtime
  except IOError:
   continue
  old_time = mtimes.get(filename, None)
  if old_time is None:
   mtimes[filename] = mtime
  elif mtime > old_time:
   return 1
 return 0

def start_change_detector():
 mtimes = {}
 while 1:
  if is_any_file_changed(mtimes):
   sys.exit(3)
  time.sleep(1)

def restart_with_reloader():
 while 1:
  args = [sys.executable] + sys.argv
  new_env = os.environ.copy()
  new_env['RUN_FLAG'] = 'true'
  exit_code = subprocess.call(args, env=new_env)
  if exit_code != 3:
   return exit_code

def run_with_reloader(runner):
 if os.environ.get('RUN_FLAG') == 'true':
  thread.start_new_thread(runner, ())
  try:
   start_change_detector()
  except KeyboardInterrupt:
   pass
 else:
  try:
   sys.exit(restart_with_reloader())
  except KeyboardInterrupt:
   pass

測試的主模塊如下:

runner.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Runner for testing autoreload module."""

__author__="Wenjun Xiao"

import os,time

def runner():
 print "[%s]enter..." % os.getpid()
 while 1:
  time.sleep(1)
 print "[%s]runner." % os.getpid()

if __name__ == '__main__':
 from autoreload import run_with_reloader
 run_with_reloader(runner)

運行runner.py:

promissing@ubuntu:python-autoreload$ python runner.py
[11743]enter...

主程序已經運行,只不過是一致在循環(huán),可以查看此時有兩個進程:

promissing@ubuntu:~$ ps -aux|grep runner[.py]
promiss+ 11742 0.0 0.2 10928 4208 pts/0 S+ 19:34 0:00 python runner.py
promiss+ 11743 0.0 0.1 20152 4092 pts/0 Sl+ 19:34 0:00 /usr/bin/python runner.py

在編輯器中打開runner.py做一些可見的修改(增加一條打印語句)如下:

# runner.py
...
def runner():
 print "[%s]enter..." % os.getpid()
 print "[%s]Runner has changed." % os.getpid()
 while 1:
  time.sleep(1)
 print "[%s]runner." % os.getpid()
...

保存之后查看運行運行情況:

promissing@ubuntu:python-autoreload$ python runner.py 
[11743]enter...
[11772]enter...
[11772]Runner has changed.

可以看到新增的語句已經生效,繼續(xù)看進程情況:

promissing@ubuntu:~$ ps -aux|grep runner[.py]
promiss+ 11742 0.0 0.2 10928 4220 pts/0 S+ 19:34 0:00 python runner.py
promiss+ 11772 0.0 0.1 20152 4092 pts/0 Sl+ 19:37 0:00 /usr/bin/python runner.py

可以對比兩次的進程,可以看到使用守護進程模式可以簡單的實現模塊自動重新加載功能。

使用守護進程模式,有一種情況比較麻煩:如果主進程由于其他原因退出了,那么子進程還在運行:

promissing@ubuntu:~$ kill 11742
promissing@ubuntu:~$ ps -aux|grep runner[.py]
promiss+ 11772 0.0 0.1 20152 4092 pts/0 Sl 19:37 0:00 /usr/bin/python runner.py

為了重啟服務還需要通過其他方式找到子進程并結束它可以。

守護進程模式-退出問題

為了解決由于守護進程退出,而導致子進程沒有退出的問題,一種比較簡單的解決方法就是在守護進程退出的時候也把子進程結束:

# autoreload.py
...
import signal
...
_sub_proc = None

def signal_handler(*args):
 global _sub_proc
 if _sub_proc:
  print "[%s]Stop subprocess:%s" % (os.getpid(), _sub_proc.pid)
  _sub_proc.terminate()
 sys.exit(0)

def restart_with_reloader():
 signal.signal(signal.SIGTERM, signal_handler) 
 while 1:
  args = [sys.executable] + sys.argv
  new_env = os.environ.copy()
  new_env['RUN_FLAG'] = 'true'
  global _sub_proc
  _sub_proc = subprocess.Popen(args, env=new_env)
  exit_code = _sub_proc.wait()
  if exit_code != 3:
   return exit_code
...

運行,查看效果(這次沒有測試修改):

promissing@ubuntu:python-autoreload$ python runner.py
[12425]enter...
[12425]Runner has changed.
[12424]Stop subprocess:12425

另一個控制臺執(zhí)行的命令如下:

promissing@ubuntu:~$ ps -aux|grep runner[.py]
promiss+ 12424 0.2 0.2 10928 4224 pts/0 S+ 20:26 0:00 python runner.py
promiss+ 12425 0.2 0.1 20152 4092 pts/0 Sl+ 20:26 0:00 /usr/bin/python runner.py
promissing@ubuntu:~$ kill 12424
promissing@ubuntu:~$ ps -aux|grep runner[.py]
promissing@ubuntu:~$ 

已經達到我們需要的功能了嗎?等等,在控制臺上運行工程總是能很好的工作,如果是在IDE中呢?由于IDE中輸入輸出是重定向處理的,比如,在Sublime中就沒有辦法獲取到輸出信息。

因此還需要進一步完善輸出的問題。

守護進程模式-輸出問題

解決輸出問題,也很簡單,修改如下:

# autoreload.py
...
def restart_with_reloader():
 signal.signal(signal.SIGTERM, signal_handler)
 while 1:
  args = [sys.executable] + sys.argv
  new_env = os.environ.copy()
  new_env['RUN_FLAG'] = 'true'
  global _sub_proc
  _sub_proc = subprocess.Popen(args, env=new_env, stdout=subprocess.PIPE,
   stderr=subprocess.STDOUT)
  read_stdout(_sub_proc.stdout)
  exit_code = _sub_proc.wait()
  if exit_code != 3:
   return exit_code

...
def read_stdout(stdout):
 while 1:
  data = os.read(stdout.fileno(), 2**15)
  if len(data) > 0:
   sys.stdout.write(data)
  else:
   stdout.close()
   sys.stdout.flush()
   break

經過以上修改,也適合在IDE中使用守護進程模式了。

源代碼:https://github.com/wenjunxiao/python-autoreload

以上這篇Python自動重新加載模塊詳解(autoreload module)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • python plt如何保存為emf圖像

    python plt如何保存為emf圖像

    這篇文章主要介紹了python plt如何保存為emf圖像問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • PyCharm中鼠標懸停在函數上時顯示函數和幫助的解決方法

    PyCharm中鼠標懸停在函數上時顯示函數和幫助的解決方法

    這篇文章主要介紹了PyCharm中鼠標懸停在函數上時顯示函數和幫助,本文給大家分享問題解決方法,對PyCharm鼠標懸停函數上顯示函數的解決方法感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • python利用requests庫進行接口測試的方法詳解

    python利用requests庫進行接口測試的方法詳解

    在python的標準庫中,雖然提供了urllib,utllib2,httplib,但是做接口測試,requests真心好,正如官方說的,“讓HTTP服務人類”,一言以蔽之,說明一切,這篇文章主要給大家介紹了關于python利用requests庫進行接口測試的相關資料,需要的朋友可以參考下
    2018-07-07
  • python合并已經存在的sheet數據到新sheet的方法

    python合并已經存在的sheet數據到新sheet的方法

    今天小編就為大家分享一篇python合并已經存在的sheet數據到新sheet的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • Python實現多子圖繪制系統的示例詳解

    Python實現多子圖繪制系統的示例詳解

    這篇文章主要介紹了如何利用python實現多子圖繪制系統,文中的示例代碼講解詳細,具有一定的的參考價值,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-09-09
  • Python下利用BeautifulSoup解析HTML的實現

    Python下利用BeautifulSoup解析HTML的實現

    這篇文章主要介紹了Python下利用BeautifulSoup解析HTML的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • Python爬取愛奇藝電影信息代碼實例

    Python爬取愛奇藝電影信息代碼實例

    這篇文章主要介紹了Python爬取愛奇藝電影信息代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • python實現每天自動簽到領積分的示例代碼

    python實現每天自動簽到領積分的示例代碼

    這篇文章主要介紹了python實現每天自動簽到領積分的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Django零基礎入門之模板變量詳解

    Django零基礎入門之模板變量詳解

    這篇文章主要介紹了Django零基礎入門之模板變量詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Python基于Opencv識別兩張相似圖片

    Python基于Opencv識別兩張相似圖片

    這篇文章主要介紹了Python基于Opencv識別兩張相似圖片的步驟,幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下
    2021-04-04

最新評論