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

首頁(yè) 後端開(kāi)發(fā) Python教學(xué) django開(kāi)發(fā)者模式中的autoreload是怎麼達(dá)成的

django開(kāi)發(fā)者模式中的autoreload是怎麼達(dá)成的

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

? ? 在開(kāi)發(fā)django應(yīng)用的過(guò)程中,使用開(kāi)發(fā)者模式啟動(dòng)服務(wù)是特別方便的一件事,只需要python manage.py runserver 就可以運(yùn)行服務(wù),並且提供了非常人性化的autoreload機(jī)制,不需要手動(dòng)重啟程式就可以修改程式碼並看到回饋。剛接觸的時(shí)候覺(jué)得這個(gè)功能比較人性化,也沒(méi)覺(jué)得是什麼特別高大上的技術(shù)。後來(lái)有空就想著如果是我來(lái)實(shí)現(xiàn)這個(gè)autoreload會(huì)怎麼做,想了很久沒(méi)想明白,總有些地方理不清楚,看來(lái)第一反應(yīng)真是眼高手低了。於是就特別花了一些時(shí)間研究了django是怎麼實(shí)現(xiàn)autoreload的,每一步都看源碼說(shuō)話,不允許有絲毫的想當(dāng)然:

1、runserver指令。在進(jìn)入正題之前其實(shí)有一大段廢話,是關(guān)於runserver指令如何執(zhí)行的,跟主題關(guān)係不大,就簡(jiǎn)單帶一下:
指令列鍵入python manage.py runserver 後,django會(huì)去尋找runserver這個(gè)指令的執(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."







#而這個(gè)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)


這裡有關(guān)於use_reloader的判斷。如果我們?cè)趩?dòng)指令中沒(méi)有加--noreload,程式就會(huì)走autoreload.main這個(gè)函數(shù),如果加了,就會(huì)走self.inner_run,直接啟動(dòng)應(yīng)用。

其實(shí)從autoreload.main的參數(shù)也可以看出,它應(yīng)該是對(duì)self.inner_run做了一些封裝,autoreload的機(jī)制就在這些封裝當(dāng)中,下面我們繼續(xù)跟著。

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

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)


#這裡針對(duì)jpython和其他python做了區(qū)別處理,先忽略jpython;check_errors就是把對(duì)main_func進(jìn)行錯(cuò)誤處理,也先忽略??磒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

#第一次走到這裡時(shí)候,環(huán)境變數(shù)中RUN_MAIN變數(shù)不是"true", 甚至都沒(méi)有,所以走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


這裡首先起一個(gè)while循環(huán), 內(nèi)部先把RUN_MAIN改成了"true",然後用os.spawnve方法開(kāi)一個(gè)子程序(subprocess),看看os.spawnve的說(shuō)明:


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


##其實(shí)就是再調(diào)一遍命令列,又走了一遍python manage.py runserver。

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


3、子行程。上面其實(shí)有一個(gè)疑問(wèn),既然是重新啟動(dòng)了一次,為什麼子行程不會(huì)接著生成子進(jìn)程?原因就在於RUN_MAIN這個(gè)環(huán)境變量,主進(jìn)程中把它改成了true,子進(jìn)程走到python_reloader函數(shù)的時(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條件滿足了,和主行程走了不一樣的邏輯分支。在這裡,先去開(kāi)一個(gè)線程,運(yùn)行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)說(shuō)明:#?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是重要的工具。之後抽個(gè)時(shí)間看下six,mark一下。 ######然後再開(kāi)一個(gè)reloader_thread:############
===?change?==3)?    ?change?==1)
############ensure_echo_on()其實(shí)還沒(méi)看明白,似乎是針對(duì)類unix系統(tǒng)檔案處理的,先略過(guò);###USE_INOTIFY也是系統(tǒng)檔案操作相關(guān)的變量,根據(jù)inotify 是否可用選擇檢測(cè)檔案變化的方法。 ###while循環(huán),每隔1秒偵測(cè)一下檔案狀態(tài),如果是普通檔案有變化,行程退出,退出碼為3,主行程一看:退出碼是3,就重啟子行程。 。 。 。這樣就跟上面連上了;如果不是普通檔案變化,而是I18N_MODIFIED(.mo後綴的檔案變化,二進(jìn)位函式庫(kù)檔案之類的),那就reset_translations ,大概意思是把已載入過(guò)的函式庫(kù)快取清理掉,下次重新加載。 ###

  以上就是autoreload機(jī)制的流程。其中還是有些細(xì)節(jié)不是特別清楚,例如不同作業(yè)系統(tǒng)檔案變化的偵測(cè),但都是很細(xì)節(jié)的東西了,不涉及主流程??赐赀@些,我又問(wèn)了自己一遍,如果是讓我設(shè)計(jì)autoreload機(jī)制會(huì)怎麼搞。現(xiàn)在我的答案是:直接把 ?django\utils\autoreload.py 檔案拿來(lái)用啊。其實(shí)這是很獨(dú)立的模組,而且特別通用,完全可以當(dāng)作通用的autoreload解決方案,我還自己寫(xiě)個(gè)毛啊。

以上是django開(kāi)發(fā)者模式中的autoreload是怎麼達(dá)成的的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

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

查看django版本步驟:1、開(kāi)啟終端機(jī)或命令提示字元視窗;2、確保已經(jīng)安裝了Django,如果沒(méi)有安裝Django,可以使用套件管理工具來(lái)進(jìn)行安裝,輸入pip install django命令即可;3、安裝完成後,可以使用python -m django --version來(lái)查看Django的版本。

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

Django和Flask都是PythonWeb框架中的佼佼者,它們都有著自己的優(yōu)點(diǎn)和適用場(chǎng)景。本文將對(duì)這兩個(gè)框架進(jìn)行比較分析,並提供具體的程式碼範(fàn)例。開(kāi)發(fā)簡(jiǎn)介Django是一個(gè)全功能的Web框架,它的主要目的是為了快速開(kāi)發(fā)複雜的Web應(yīng)用。 Django提供了許多內(nèi)建的功能,例如ORM(物件關(guān)聯(lián)映射)、表單、認(rèn)證、管理後臺(tái)等。這些功能使得Django在處理大型

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

Django是一個(gè)完整的開(kāi)發(fā)框架,該框架涵蓋了Web開(kāi)發(fā)生命週期的各個(gè)方面。目前,這個(gè)框架是全球最受歡迎的Web框架之一。如果你打算使用Django來(lái)建立自己的Web應(yīng)用程序,那麼你需要了解Django框架的優(yōu)點(diǎn)和缺點(diǎn)。以下是您需要知道的一切,包括具體程式碼範(fàn)例。 Django優(yōu)點(diǎn):1.快速開(kāi)發(fā)-Djang可以快速開(kāi)發(fā)Web應(yīng)用程式。它提供了豐富的庫(kù)和內(nèi)

如何升級(jí)Django版本:步驟與注意事項(xiàng) 如何升級(jí)Django版本:步驟與注意事項(xiàng) Jan 19, 2024 am 10:16 AM

如何升級(jí)Django版本:步驟和注意事項(xiàng),需要具體程式碼範(fàn)例引言:Django是一個(gè)功能強(qiáng)大的PythonWeb框架,它持續(xù)地進(jìn)行更新和升級(jí),以提供更好的效能和更多的功能。然而,對(duì)於使用較舊版Django的開(kāi)發(fā)者來(lái)說(shuō),升級(jí)Django可能會(huì)面臨一些挑戰(zhàn)。本文將介紹如何升級(jí)Django版本的步驟和注意事項(xiàng),並提供具體的程式碼範(fàn)例。一、備份項(xiàng)目檔案在升級(jí)Djan

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

差異是: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開(kāi)發(fā)功能;2、Django 2.x系列:這是Django的中期版本,包括2.0、2.1、2.2等版本;3、Django 3.x系列:這是Django的最新版本系列,包括3.0、3等版本。

天貓精靈雲(yún)端存取服務(wù)升級(jí):免費(fèi)開(kāi)發(fā)者收費(fèi) 天貓精靈雲(yún)端存取服務(wù)升級(jí):免費(fèi)開(kāi)發(fā)者收費(fèi) Jan 09, 2024 pm 10:06 PM

本站1月9日消息,天貓精靈日前發(fā)布雲(yún)端雲(yún)端接入服務(wù)升級(jí)的公告,升級(jí)後的雲(yún)端雲(yún)端存取服務(wù)從1月1日起從免費(fèi)模式變更為付費(fèi)。本站附新增功能與最佳化:優(yōu)化雲(yún)端協(xié)議,提升裝置連線的穩(wěn)定性;優(yōu)化重點(diǎn)品類的語(yǔ)音控制;帳號(hào)授權(quán)升級(jí):新增天貓精靈中開(kāi)發(fā)者三方App的展示功能,幫助使用者更快更方便進(jìn)行帳號(hào)綁定,同時(shí)新增開(kāi)發(fā)者三方App帳號(hào)授權(quán)支援一鍵綁定天貓精靈帳號(hào);新增終端屏顯互動(dòng)能力,除語(yǔ)音互動(dòng)外,用戶可透過(guò)app、帶屏音箱控制設(shè)備、取得設(shè)備狀態(tài);新增智慧場(chǎng)景連動(dòng)能力,新產(chǎn)品的屬性、事件,可作為狀態(tài)或事件上報(bào),定義天貓

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

查看django版本的方法:1、透過(guò)命令列查看,在終端機(jī)或命令列視窗中輸入「python -m django --version」命令;2、在Python互動(dòng)式環(huán)境中查看,輸入「import django print(django. get_version())」代碼;3、檢查Django專案的設(shè)定文件,找到名為INSTALLED_APPS的列表,其中包含已安裝的應(yīng)用程式資訊。

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

Django是一個(gè)由Python編寫(xiě)的web應(yīng)用框架,它強(qiáng)調(diào)快速開(kāi)發(fā)和乾淨(jìng)方法。儘管Django是web框架,但要回答Django是前端還是後端這個(gè)問(wèn)題,需要深入理解前後端的概念。前端是指使用者直接和互動(dòng)的介面,後端是指伺服器端的程序,他們透過(guò)HTTP協(xié)定進(jìn)行資料的互動(dòng)。在前端和後端分離的情況下,前後端程式可以獨(dú)立開(kāi)發(fā),分別實(shí)現(xiàn)業(yè)務(wù)邏輯和互動(dòng)效果,資料的交

See all articles