搜尋
首頁後端開發Python教學django開發者模式中的autoreload是怎麼達成的

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

1、runserver指令。在進入正題之前其實有一大段廢話,是關於runserver指令如何執行的,跟主題關係不大,就簡單帶一下:
指令列鍵入python manage.py runserver 後,django會去尋找runserver這個指令的執行模組,最後落在
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的執行函數在這裡:


#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這個函數,如果加了,就會走self.inner_run,直接啟動應用。

其實從autoreload.main的參數也可以看出,它應該是對self.inner_run做了一些封裝,autoreload的機制就在這些封裝當中,下面我們繼續跟著。

PS: 看原始碼的時候發現django的command模式還是實現的很漂亮的,值得學習。

2、autoreload模組。看autoreload.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做了區別處理,先忽略jpython;check_errors就是把對main_func進行錯誤處理,也先忽略。看python_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 <p></p><p>#第一次走到這裡時候,環境變數中RUN_MAIN變數不是"true", 甚至都沒有,所以走else, 看restart_with_reloader:</p><p class="cnblogs_code"><br></p><pre class="brush:php;toolbar:false">#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循環, 內部先把RUN_MAIN改成了"true",然後用os.spawnve方法開一個子程序(subprocess),看看os.spawnve的說明:


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


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

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


3、子行程。上面其實有一個疑問,既然是重新啟動了一次,為什麼子行程不會接著生成子進程?原因就在於RUN_MAIN這個環境變量,主進程中把它改成了true,子進程走到python_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 <p></p><p></p>#if條件滿足了,和主行程走了不一樣的邏輯分支。在這裡,先去開一個線程,運行main_func,就是上文的 Command.inner_run。這裡的thread模組是這麼import的:<p class="cnblogs_code"><br></p><p></p><pre class="brush:php;toolbar:false">#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"""官网说明:# 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系統檔案處理的,先略過;###USE_INOTIFY也是系統檔案操作相關的變量,根據inotify 是否可用選擇檢測檔案變化的方法。 ###while循環,每隔1秒偵測一下檔案狀態,如果是普通檔案有變化,行程退出,退出碼為3,主行程一看:退出碼是3,就重啟子行程。 。 。 。這樣就跟上面連上了;如果不是普通檔案變化,而是I18N_MODIFIED(.mo後綴的檔案變化,二進位函式庫檔案之類的),那就reset_translations ,大概意思是把已載入過的函式庫快取清理掉,下次重新加載。 ###

  以上就是autoreload機制的流程。其中還是有些細節不是特別清楚,例如不同作業系統檔案變化的偵測,但都是很細節的東西了,不涉及主流程。看完這些,我又問了自己一遍,如果是讓我設計autoreload機制會怎麼搞。現在我的答案是:直接把  django\utils\autoreload.py 檔案拿來用啊。其實這是很獨立的模組,而且特別通用,完全可以當作通用的autoreload解決方案,我還自己寫個毛啊。

以上是django開發者模式中的autoreload是怎麼達成的的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
怎么将Django项目迁移到linux系统中怎么将Django项目迁移到linux系统中Jun 01, 2023 pm 01:07 PM

Django项目配置修改我们需要把原先的Django项目进行修改才能更好地进行项目迁移工作,首先需要修改的是settings.py文件。由于项目上线之后不能让用户看到后台的运行逻辑,所以我们要把DEBUG改成False,把ALLOWED_HOSTS写成&lsquo;*&rsquo;,这样是为了允许从不同主机进行访问。由于linux中如果不加这句可能会出现文件找不到的情况,所以我们要把模板的路径进行拼接。由于做Django项目肯定进行过数据库的同步,所以我们要把migrations

centos+nginx+uwsgi部署django项目上线的方法centos+nginx+uwsgi部署django项目上线的方法May 15, 2023 am 08:13 AM

我django项目叫yunwei,主要app是rabc和web,整个项目放/opt/下如下:[root@test-codeopt]#lsdjango_virtnginxredisredis-6.2.6yunwei[root@test-codeopt]#lsyunwei/manage.pyrbacstatictemplatesuwsgiwebyunwei[root@test-codeopt]#lsyunwei/uwsgi/cut_log.shloguwsgi.iniuwsgi.loguwsgi.p

Django框架中的数据库迁移技巧Django框架中的数据库迁移技巧Jun 17, 2023 pm 01:10 PM

Django是一个使用Python语言编写的Web开发框架,其提供了许多方便的工具和模块来帮助开发人员快速地搭建网站和应用程序。其中最重要的一个特性就是数据库迁移功能,它可以帮助我们简单地管理数据库模式的变化。在本文中,我们将会介绍一些在Django中使用数据库迁移的技巧,包括如何开始一个新的数据库迁移、如何检测数据库迁移冲突、如何查看历史数据库迁移记录等等

Django框架中的文件上传技巧Django框架中的文件上传技巧Jun 18, 2023 am 08:24 AM

近年来,Web应用程序逐渐流行,而其中许多应用程序都需要文件上传功能。在Django框架中,实现上传文件功能并不困难,但是在实际开发中,我们还需要处理上传的文件,其他操作包括更改文件名、限制文件大小等问题。本文将分享一些Django框架中的文件上传技巧。一、配置文件上传项在Django项目中,要配置文件上传需要在settings.py文件中进

如何用nginx+uwsgi部署自己的django项目如何用nginx+uwsgi部署自己的django项目May 12, 2023 pm 10:10 PM

第一步:换源输入命令换掉Ubuntu的下载源sudonano/etc/apt/sources.list将以下全部替换掉原文件,我这里用的是阿里的源,你也可以换其他的。debhttp://mirrors.aliyun.com/ubuntu/bionicmainrestricteddebhttp://mirrors.aliyun.com/ubuntu/bionic-updatesmainrestricteddebhttp://mirrors.aliyun.com/ubuntu/bionicunive

使用Django构建RESTful API使用Django构建RESTful APIJun 17, 2023 pm 09:29 PM

Django是一个Web框架,可以轻松地构建RESTfulAPI。RESTfulAPI是一种基于Web的架构,可以通过HTTP协议访问。在这篇文章中,我们将介绍如何使用Django来构建RESTfulAPI,包括如何使用DjangoREST框架来简化开发过程。安装Django首先,我们需要在本地安装Django。可以使用pip来安装Django,具体

使用Python Django框架构建博客网站使用Python Django框架构建博客网站Jun 17, 2023 pm 03:37 PM

随着互联网的普及,博客在信息传播和交流方面扮演着越来越重要的角色。在此背景下,越来越多的人开始构建自己的博客网站。本文将介绍如何使用PythonDjango框架来构建自己的博客网站。一、PythonDjango框架简介PythonDjango是一个免费的开源Web框架,可用于快速开发Web应用程序。该框架为开发人员提供了强大的工具,可帮助他们构建功能丰

Django+Bootstrap构建响应式管理后台系统Django+Bootstrap构建响应式管理后台系统Jun 17, 2023 pm 05:27 PM

随着互联网技术的快速发展和企业业务的不断扩展,越来越多的企业需要建立自己的管理后台系统,以便于更好地管理业务和数据。而现在,使用Django框架和Bootstrap前端库构建响应式管理后台系统的趋势也越来越明显。本文将介绍如何利用Django和Bootstrap构建一个响应式的管理后台系统。Django是一种基于Python语言的Web框架,它提供了丰富的功

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 Mac版

SublimeText3 Mac版

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

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境