国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 后端開發(fā) Python教程 django開發(fā)者模式中的autoreload是怎樣實現(xiàn)的

django開發(fā)者模式中的autoreload是怎樣實現(xiàn)的

Aug 19, 2017 pm 02:47 PM
django 開發(fā)者

? ? 在開發(fā)django應用的過程中,使用開發(fā)者模式啟動服務是特別方便的一件事,只需要 python manage.py runserver 就可以運行服務,并且提供了非常人性化的autoreload機制,不需要手動重啟程序就可以修改代碼并看到反饋。剛接觸的時候覺得這個功能比較人性化,也沒覺得是什么特別高大上的技術。后來有空就想著如果是我來實現(xiàn)這個autoreload會怎么做,想了很久沒想明白,總有些地方理不清楚,看來第一反應真是眼高手低了。于是就專門花了一些時間研究了django是怎樣實現(xiàn)autoreload的,每一步都看源碼說話,不允許有絲毫的想當然:

1、runserver命令。在進入正題之前其實有一大段廢話,是關于runserver命令如何執(zhí)行的,和主題關系不大,就簡單帶一下:
命令行鍵入 python manage.py runserver 后,django會去尋找runserver這個命令的執(zhí)行模塊,最后落在
django\contrib\staticfiles\management\commands\runserver.py模塊上:


#django\contrib\staticfiles\management\commands\runserver.pyfrom?django.core.management.commands.runserver?import?\
Command?as?RunserverCommandclass?Command(RunserverCommand):
  help?=?"Starts?a?lightweight?Web?server?for?development?and?also?serves?static?files."


而這個Command的執(zhí)行函數(shù)在這:


#django\core\management\commands\runserver.pyclass?Command(BaseCommand):
  def?run(self,?**options):
  """  Runs?the?server,?using?the?autoreloader?if?needed
  """  use_reloader?=?options['use_reloader']

  if?use_reloader:
    autoreload.main(self.inner_run,?None,?options)
  else:
    self.inner_run(None,?**options)


這里有關于use_reloader的判斷。如果我們在啟動命令中沒有加--noreload,程序就會走autoreload.main這個函數(shù),如果加了,就會走self.inner_run,直接啟動應用。
其實從autoreload.main的參數(shù)也可以看出,它應該是對self.inner_run做了一些封裝,autoreload的機制就在這些封裝當中,下面我們繼續(xù)跟。

PS: 看源碼的時候發(fā)現(xiàn)django的command模式還是實現(xiàn)的很漂亮的,值得學習。

2、autoreload模塊??碼utoreload.main():


#django\utils\autoreload.py:def?main(main_func,?args=None,?kwargs=None):
  if?args?is?None:
    args?=?()
  if?kwargs?is?None:
    kwargs?=?{}
  if?sys.platform.startswith('java'):
    reloader?=?jython_reloader
  else:
    reloader?=?python_reloader

  wrapped_main_func?=?check_errors(main_func)
  reloader(wrapped_main_func,?args,?kwargs)


這里針對jpython和其他python做了區(qū)別處理,先忽略jpython;check_errors就是把對main_func進行錯誤處理,也先忽略??磒ython_reloader:


#django\utils\autoreload.py:def?python_reloader(main_func,?args,?kwargs):
  if?os.environ.get("RUN_MAIN")?==?"true":
    thread.start_new_thread(main_func,?args,?kwargs)
    try:
      reloader_thread()
    except?KeyboardInterrupt:
      pass  else:
    try:
      exit_code?=?restart_with_reloader()
      if?exit_code?<?0:
        os.kill(os.getpid(),?-exit_code)
      else:
        sys.exit(exit_code)
    except?KeyboardInterrupt:
      pass


第一次走到這里時候,環(huán)境變量中RUN_MAIN變量不是"true", 甚至都沒有,所以走else, 看restart_with_reloader:


#django\utils\autoreload.py:def?restart_with_reloader():????while?True:
????  args?=?[sys.executable]?+?['-W%s'?%?o?for?o?in?sys.warnoptions]?+?sys.argv
    if?sys.platform?==?"win32":
      args?=?['"%s"'?%?arg?for?arg?in?args]
    new_environ?=?os.environ.copy()
    new_environ["RUN_MAIN"]?=?'true'    exit_code?=?os.spawnve(os.P_WAIT,?sys.executable,?args,?new_environ)
    if?exit_code?!=?3:
      return?exit_code


這里首先起一個while循環(huán), 內部先把RUN_MAIN改成了"true",然后用os.spawnve方法開一個子進程(subprocess),看看os.spawnve的說明:


  ?_spawnvef(mode,?file,?args,?env,?execve)


其實就是再調一遍命令行,又走了一遍 python manage.py runserver。

接著看restart_with_reloader里的while循環(huán),需要注意的是while循環(huán)退出的唯一條件是exit_code!=3。 如果子進程不退出,就一直停在 os.spawnve這一步; 如果子進程退出,而退出碼不是3,while就被終結了;如果是3,繼續(xù)循環(huán),重新創(chuàng)建子進程。從這個邏輯可以猜想autoreload的機制:當前進程(主進程)其實啥也不干,就監(jiān)視子進程的運行狀況,子進程才是真正干事兒的;如果子進程以exit_code=3退出(應該由于檢測到了文件修改),就再啟動一遍子進程,新代碼自然就生效了;如果子進程以exit_code!=3退出,主進程也結束,整個django程序就算跪了。這只是猜想,下面接著來驗證。

3、子進程。上面其實有一個疑問,既然是重新啟動了一次,為什么子進程不會接著生成子進程?原因就在于RUN_MAIN這個環(huán)境變量,主進程中把它改成了true,子進程走到python_reloader函數(shù)的時候:


#django\utils\autoreload.py:def?python_reloader(main_func,?args,?kwargs):
  if?os.environ.get("RUN_MAIN")?==?"true":
    thread.start_new_thread(main_func,?args,?kwargs)
    try:
      reloader_thread()
    except?KeyboardInterrupt:
      pass  else:
    try:
      exit_code?=?restart_with_reloader()
      if?exit_code?<?0:
        os.kill(os.getpid(),?-exit_code)
      else:
        sys.exit(exit_code)
    except?KeyboardInterrupt:
      pass


if條件滿足了,和主進程走了不一樣的邏輯分支。在這里,首先去開一個線程,運行main_func,就是上文的 Command.inner_run。這里的thread模塊是這么import的:


#django\utils\autoreload.py:from?django.utils.six.moves?import?_thread?as?thread


這里six模塊的作用是兼容各種python版本:


[codeblock?six]#django\utils\six.pyclass?_SixMetaPathImporter(object):"""A?meta?path?importer?to?import?six.moves?and?its?submodules.

This?class?implements?a?PEP302?finder?and?loader.?It?should?be?compatible
with?Python?2.5?and?all?existing?versions?of?Python3"""官網(wǎng)說明:#?https://pythonhosted.org/six/Six:?Python?2?and?3?Compatibility?Library
Six?provides?simple?utilities?for?wrapping?over?differences?between?Python?2?and?Python?3.?It?is?intended?to?support?codebases?that?work?on?both?Python?2?and?3?without?modification.?six?consists?of?only?one?Python?file,?so?it?is?painless?to?copy?into?a?project.


所以如果程序想在python2和python3上都能跑,且魯邦,six是重要的工具。之后抽個時間看下six,mark一下。

然后再開一個reloader_thread:


===?change?==3)?    ?change?==1)


ensure_echo_on()其實還沒看明白,貌似是針對類unix系統(tǒng)文件處理的,先略過;
USE_INOTIFY也是系統(tǒng)文件操作相關的變量,根據(jù) inotify 是否可用選擇檢測文件變化的方法。
while循環(huán),每隔1秒檢測一下文件狀態(tài),如果是普通文件有變化,進程退出,退出碼為3,主進程一看:退出碼是3,就重啟子進程。。。。這樣就和上面連上了;如果不是普通文件變化,而是I18N_MODIFIED(.mo后綴的文件變化,二進制庫文件之類的),那就 reset_translations ,大概意思是把已加載過的庫緩存清理掉,下次重新加載。

  以上就是autoreload機制的流程。其中還是有些細節(jié)不是特別清楚,比如不同操作系統(tǒng)文件變化的檢測,但都是很細節(jié)的東西了,不涉及主流程??赐赀@些,我又問了自己一遍,如果是讓我設計autoreload機制會怎樣搞?,F(xiàn)在我的答案是:直接把 ?django\utils\autoreload.py 文件拿來用啊。其實這是很獨立的一個模塊,而且特別通用,完全可以作為通用的autoreload解決方案,我還自己寫個毛啊。

以上是django開發(fā)者模式中的autoreload是怎樣實現(xiàn)的的詳細內容。更多信息請關注PHP中文網(wǎng)其他相關文章!

本站聲明
本文內容由網(wǎng)友自發(fā)貢獻,版權歸原作者所有,本站不承擔相應法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權的內容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅動的應用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

怎么看django版本 怎么看django版本 Dec 01, 2023 pm 02:25 PM

查看django版本步驟:1、打開終端或命令提示符窗口;2、確保已經(jīng)安裝了Django,如果沒有安裝Django,可以使用包管理工具來進行安裝,輸入pip install django命令即可;3、安裝完成后,可以使用python -m django --version來查看Django的版本。

Django vs. Flask:Python Web框架的對比分析 Django vs. Flask:Python Web框架的對比分析 Jan 19, 2024 am 08:36 AM

Django和Flask都是PythonWeb框架中的佼佼者,它們都有著自己的優(yōu)點和適用場景。本文將對這兩個框架進行對比分析,并提供具體的代碼示例。開發(fā)簡介Django是一個全功能的Web框架,它的主要目的是為了快速開發(fā)復雜的Web應用。Django提供了許多內置的功能,比如ORM(對象關系映射)、表單、認證、管理后臺等。這些功能使得Django在處理大型

Django框架的優(yōu)點和缺點:您需要知道的一切 Django框架的優(yōu)點和缺點:您需要知道的一切 Jan 19, 2024 am 09:09 AM

Django是一個完整的開發(fā)框架,該框架涵蓋了Web開發(fā)生命周期的各個方面。目前,這個框架是全球范圍內最流行的Web框架之一。如果你打算使用Django來構建自己的Web應用程序,那么你需要了解Django框架的優(yōu)點和缺點。以下是您需要知道的一切,包括具體代碼示例。Django優(yōu)點:1.快速開發(fā)-Djang可以快速開發(fā)Web應用程序。它提供了豐富的庫和內

如何升級Django版本:步驟和注意事項 如何升級Django版本:步驟和注意事項 Jan 19, 2024 am 10:16 AM

如何升級Django版本:步驟和注意事項,需要具體代碼示例引言:Django是一個功能強大的PythonWeb框架,它持續(xù)地進行更新和升級,以提供更好的性能和更多的功能。然而,對于使用較舊版本Django的開發(fā)者來說,升級Django可能會面臨一些挑戰(zhàn)。本文將介紹如何升級Django版本的步驟和注意事項,并提供具體的代碼示例。一、備份項目文件在升級Djan

django版本區(qū)別是什么 django版本區(qū)別是什么 Nov 20, 2023 pm 04:33 PM

區(qū)別是:1、Django 1.x系列:這是Django的早期版本,包括1.0、1.1、1.2、1.3、1.4、1.5、1.6、1.7、1.8和1.9等版本。這些版本主要提供基本的Web開發(fā)功能;2、Django 2.x系列:這是Django的中期版本,包括2.0、2.1、2.2等版本;3、Django 3.x系列:這是Django的最新版本系列,包括3.0、3等版本。

天貓精靈云云接入服務升級:免費開發(fā)者收費 天貓精靈云云接入服務升級:免費開發(fā)者收費 Jan 09, 2024 pm 10:06 PM

本站1月9日消息,天貓精靈日前發(fā)布云云接入服務升級的公告,升級后的云云接入服務從1月1日起從免費模式變更為付費。本站附新增功能和優(yōu)化:優(yōu)化云端協(xié)議,提升設備連接的穩(wěn)定性;優(yōu)化重點品類的語音控制;賬號授權升級:新增天貓精靈中開發(fā)者三方App的展示功能,幫助用戶更快更方便進行賬號綁定,同時新增開發(fā)者三方App賬號授權支持一鍵綁定天貓精靈賬號;新增終端屏顯交互能力,除語音交互外,用戶可通過app、帶屏音箱控制設備、獲取設備狀態(tài);新增智能場景聯(lián)動能力,新建產(chǎn)品的屬性、事件,可作為狀態(tài)或事件上報,定義天貓

怎么查看django版本 怎么查看django版本 Nov 30, 2023 pm 03:08 PM

查看django版本的方法:1、通過命令行查看,在終端或命令行窗口中輸入“python -m django --version”命令;2、在Python交互式環(huán)境中查看,輸入“import django print(django.get_version())”代碼;3、檢查Django項目的設置文件,找到名為INSTALLED_APPS的列表,其中包含已安裝的應用程序信息。

Django是前端還是后端?一探究竟! Django是前端還是后端?一探究竟! Jan 19, 2024 am 08:37 AM

Django是一個Python編寫的web應用框架,它強調快速開發(fā)和干凈方法。盡管Django是一個web框架,但是要回答Django是前端還是后端這個問題,需要深入理解前后端的概念。前端是指用戶直接和交互的界面,后端是指服務器端的程序,他們通過HTTP協(xié)議進行數(shù)據(jù)的交互。在前端和后端分離的情況下,前后端程序可以獨立開發(fā),分別實現(xiàn)業(yè)務邏輯和交互效果,數(shù)據(jù)的交

See all articles