在開發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."
#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)
其實從autoreload.main的參數也可以看出,它應該是對self.inner_run做了一些封裝,autoreload的機制就在這些封裝當中,下面我們繼續跟著。
PS: 看原始碼的時候發現django的command模式還是實現的很漂亮的,值得學習。
#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)
#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)
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中文網其他相關文章!

Tomergelistsinpython,YouCanusethe操作員,estextMethod,ListComprehension,Oritertools

在Python3中,可以通過多種方法連接兩個列表:1)使用 運算符,適用於小列表,但對大列表效率低;2)使用extend方法,適用於大列表,內存效率高,但會修改原列表;3)使用*運算符,適用於合併多個列表,不修改原列表;4)使用itertools.chain,適用於大數據集,內存效率高。

使用join()方法是Python中從列表連接字符串最有效的方法。 1)使用join()方法高效且易讀。 2)循環使用 運算符對大列表效率低。 3)列表推導式與join()結合適用於需要轉換的場景。 4)reduce()方法適用於其他類型歸約,但對字符串連接效率低。完整句子結束。

pythonexecutionistheprocessoftransformingpypythoncodeintoExecutablestructions.1)InternterPreterReadSthecode,ConvertingTingitIntObyTecode,whepythonvirtualmachine(pvm)theglobalinterpreterpreterpreterpreterlock(gil)the thepythonvirtualmachine(pvm)

Python的關鍵特性包括:1.語法簡潔易懂,適合初學者;2.動態類型系統,提高開發速度;3.豐富的標準庫,支持多種任務;4.強大的社區和生態系統,提供廣泛支持;5.解釋性,適合腳本和快速原型開發;6.多範式支持,適用於各種編程風格。

Python是解釋型語言,但也包含編譯過程。 1)Python代碼先編譯成字節碼。 2)字節碼由Python虛擬機解釋執行。 3)這種混合機制使Python既靈活又高效,但執行速度不如完全編譯型語言。

UseeAforloopWheniteratingOveraseQuenceOrforAspecificnumberoftimes; useAwhiLeLoopWhenconTinuingUntilAcIntiment.forloopsareIdealForkNownsences,而WhileLeleLeleLeleLeleLoopSituationSituationsItuationsItuationSuationSituationswithUndEtermentersitations。

pythonloopscanleadtoerrorslikeinfiniteloops,modifyingListsDuringteritation,逐個偏置,零indexingissues,andnestedloopineflinefficiencies


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

SublimeText3 Linux新版
SublimeText3 Linux最新版

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

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