recherche
Maisondéveloppement back-endTutoriel PythonComment le rechargement automatique est-il implémenté en mode développeur Django ?

Dans le processus de développement d'applications Django, il est particulièrement pratique d'utiliser le mode développeur pour démarrer les services. Vous n'avez besoin que de python manage.py runserver pour exécuter le service, et il fournit un mécanisme de rechargement automatique très convivial, qui n'est pas nécessaire. nécessite une opération manuelle. Redémarrez le programme pour modifier le code et voir les commentaires. Lorsque je l’ai découvert pour la première fois, je pensais que cette fonction était plus conviviale et je ne pensais pas qu’il s’agissait d’une technologie particulièrement avancée. Plus tard, quand j'avais du temps libre, j'ai réfléchi à ce que je ferais si je devais implémenter ce rechargement automatique. Après avoir longuement réfléchi, je n'arrivais pas à comprendre. Il y avait toujours des choses que je n'arrivais pas à comprendre. . Il semble que ma première réaction ait été que j’avais trop d’ambition et pas assez de compétences. J'ai donc passé du temps à étudier comment Django implémente le rechargement automatique, j'ai regardé le code source pour chaque étape et je n'ai rien laissé pour acquis :

1. Avant d'entrer dans le sujet, il y a en fait un long paragraphe d'absurdités sur la façon dont la commande runserver est exécutée. Cela n'a pas grand-chose à voir avec le sujet, je vais donc le mentionner brièvement :
Après avoir tapé python manage.py runserver sur le ligne de commande, Django va chercher la commande runserver. Le module d'exécution tombe finalement sur le module
djangocontribstaticfilesmanagementcommandsrunserver.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."


.

La fonction d'exécution de cette commande est ici :


#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)


Voici les jugements sur use_reloader. Si nous n'ajoutons pas --noreload dans la commande de démarrage, le programme ira à la fonction autoreload.main Si nous l'ajoutons, il ira à self.inner_run et démarrera directement l'application.
En fait, il ressort des paramètres de autoreload.main qu'il devrait avoir une certaine encapsulation de self.inner_run. Le mécanisme de rechargement automatique est dans ces encapsulations.

PS : Quand j'ai regardé le code source, j'ai trouvé que le mode commande de Django est magnifiquement implémenté et mérite d'être appris.

2. module de rechargement automatique. Regardez 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)


Ici, nous faisons une distinction entre jpython et les autres pythons, ignorez d'abord jpython ; check_errors Ignorez simplement la gestion des erreurs de main_func. Regardez 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><br></p><p>Quand je suis arrivé ici pour la première fois, la variable RUN_MAIN dans la variable d'environnement n'était pas "true", ou même Non, alors allez ailleurs et regardez 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


Ici, nous démarrons d'abord une boucle while et modifions en interne RUN_MAIN sur "true", puis utilisez la méthode os.spawnve pour ouvrir un sous-processus (sous-processus), jetez un œil aux instructions de os.spawnve :


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


En fait, je viens d'ajuster à nouveau la ligne de commande et d'exécuter à nouveau python manage.py runserver.

Ensuite, regardez la boucle while dans restart_with_reloader. Il convient de noter que la seule condition pour que la boucle while se termine est exit_code!=3. Si le processus enfant ne se termine pas, il s'arrêtera à l'étape os.spawnve ; si le processus enfant se termine et que le code de sortie n'est pas 3, le while est terminé s'il est 3, la boucle continue et le processus enfant est terminé ; recréé. À partir de cette logique, nous pouvons deviner le mécanisme de rechargement automatique : le processus actuel (processus principal) ne fait rien, mais surveille l'état d'exécution du processus enfant. Le processus enfant est réel si le processus enfant se termine avec exit_code=3 ; (cela devrait être dû à une détection lorsque le fichier est modifié), redémarrez le sous-processus et le nouveau code prendra naturellement effet si le sous-processus se termine avec exit_code!=3, le processus principal se terminera également et ; tout le programme Django sera arrêté. Ceci n’est qu’une conjecture et sera vérifiée ci-dessous.

3. Processus enfant. Il y a en fait une question ci-dessus puisqu'il a été redémarré, pourquoi le processus enfant ne génère-t-il pas de processus enfants ? La raison en est que la variable d'environnement RUN_MAIN est remplacée par true dans le processus principal lorsque le processus enfant accède à la fonction 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><br></p>Si la condition est remplie, cela prendra une branche logique différente du processus principal. Ici, ouvrez d’abord un fil de discussion et exécutez main_func, qui est Command.inner_run ci-dessus. Le module thread ici est importé comme ceci : <p></p><p class="cnblogs_code"><br></p><pre class="brush:php;toolbar:false">#django\utils\autoreload.py:from django.utils.six.moves import _thread as thread


Le rôle du module six ici est d'être compatible avec divers python versions :


[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.


Donc, si le programme veut fonctionner à la fois sur python2 et python3, et sur Lupin, six est un outil important. Ensuite, prenez le temps d’en regarder six et de le noter.

Ensuite, ouvrez un reloader_thread :


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


ensure_echo_on() En fait, je ne l'ai pas encore compris, il semble que pour le traitement des fichiers système de type Unix, ignorez-le d'abord ;

USE_INOTIFY est également une variable liée aux opérations sur les fichiers système. Choisissez la méthode pour détecter les modifications de fichiers en fonction de la disponibilité ou non d'inotify.
En boucle While, vérifiez l'état du fichier toutes les 1 secondes. S'il y a un changement dans le fichier ordinaire, le processus se terminera avec un code de sortie de 3. Lorsque le processus principal verra que le code de sortie est 3, il redémarrera. le processus enfant. . . . Ceci est lié à ce qui précède ; s'il ne s'agit pas d'un changement de fichier ordinaire, mais de I18N_MODIFIED (changement de fichier avec le suffixe .mo, fichier de bibliothèque binaire, etc.), alors reset_translations, ce qui signifie probablement vider le cache de la bibliothèque chargée la prochaine fois. .

Ce qui précède est le processus du mécanisme de rechargement automatique. Il y a encore quelques détails qui ne sont pas particulièrement clairs, comme la détection des modifications de fichiers dans différents systèmes d'exploitation, mais ce sont des choses très détaillées et n'impliquent pas le processus principal. Après avoir lu ceci, je me suis demandé à nouveau : que ferais-je si on me demandait de concevoir le mécanisme de rechargement automatique ? Maintenant, ma réponse est : utilisez directement le fichier djangoutilsautoreload.py. En fait, il s'agit d'un module très indépendant et très polyvalent. Il peut être utilisé comme solution de rechargement automatique universelle. Je l'ai même écrit moi-même.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Quelles sont les opérations communes qui peuvent être effectuées sur des tableaux Python?Quelles sont les opérations communes qui peuvent être effectuées sur des tableaux Python?Apr 26, 2025 am 12:22 AM

PythonarRaySSupportVariousOperations: 1) SpecingExtractsSubSets, 2) A SPENDANT / EXPENSEDADDDSELLESS, 3) INSERtingPlaceSelelementsAtSpecific Positions, 4) RemovingdeleteSelements, 5) Sorting / ReversingChangeSes

Dans quels types d'applications les tableaux Numpy sont-ils couramment utilisés?Dans quels types d'applications les tableaux Numpy sont-ils couramment utilisés?Apr 26, 2025 am 12:13 AM

NumpyArraysAressentialFor Applications est en train de réaliser des objets de manière numérique et une datamanipulation.

Quand choisiriez-vous d'utiliser un tableau sur une liste dans Python?Quand choisiriez-vous d'utiliser un tableau sur une liste dans Python?Apr 26, 2025 am 12:12 AM

Useanarray.arrayoveralistinpythonwendealing withhomogeneousdata, performance-criticalcode, orinterfacingwithccode.1) homogeneousdata: ArraySaveMemorywithTypelements.2) performance-criticalcode

Toutes les opérations de liste sont-elles prises en charge par des tableaux, et vice versa? Pourquoi ou pourquoi pas?Toutes les opérations de liste sont-elles prises en charge par des tableaux, et vice versa? Pourquoi ou pourquoi pas?Apr 26, 2025 am 12:05 AM

Non, NotallListOperationsResaSupportedByArrays, andviceVersa.1) ArraysDonotsUpportDynamicOperationsLIKEAPENDORINSERSERTWithoutresizing, qui oblige la performance.2) Listes de la glate-enconteConStanttimecomplexityfordirectAccessLikEArraysDo.

Comment accéder aux éléments dans une liste de python?Comment accéder aux éléments dans une liste de python?Apr 26, 2025 am 12:03 AM

TOACCESSELlementsInapyThonList, Use Indexing, Négatif Indexing, Specing, Oriteration.1) IndexingStarTsat0.2) négatif Indexing Accesssheend.3) SlicingExtractSports.4) itérationussesforloopsoReNumerate.

Comment les tableaux sont-ils utilisés dans l'informatique scientifique avec Python?Comment les tableaux sont-ils utilisés dans l'informatique scientifique avec Python?Apr 25, 2025 am 12:28 AM

ArraySinpython, en particulier Vianumpy, arecrucialinsciciencomputingfortheirefficiency andversatity.1) ils sont les opérations de data-analyse et la machineauning.2)

Comment gérez-vous différentes versions Python sur le même système?Comment gérez-vous différentes versions Python sur le même système?Apr 25, 2025 am 12:24 AM

Vous pouvez gérer différentes versions Python en utilisant Pyenv, Venv et Anaconda. 1) Utilisez PYENV pour gérer plusieurs versions Python: installer PYENV, définir les versions globales et locales. 2) Utilisez VENV pour créer un environnement virtuel pour isoler les dépendances du projet. 3) Utilisez Anaconda pour gérer les versions Python dans votre projet de science des données. 4) Gardez le Système Python pour les tâches au niveau du système. Grâce à ces outils et stratégies, vous pouvez gérer efficacement différentes versions de Python pour assurer le bon fonctionnement du projet.

Quels sont les avantages de l'utilisation de tableaux Numpy sur des tableaux Python standard?Quels sont les avantages de l'utilisation de tableaux Numpy sur des tableaux Python standard?Apr 25, 2025 am 12:21 AM

NumpyArrayShaveSeveralAdvantages OverStandardPyThonarRays: 1) TheaReMuchfasterDuetoc-bases Implementation, 2) Ils sont économisés par le therdémor

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

DVWA

DVWA

Damn Vulnerable Web App (DVWA) est une application Web PHP/MySQL très vulnérable. Ses principaux objectifs sont d'aider les professionnels de la sécurité à tester leurs compétences et leurs outils dans un environnement juridique, d'aider les développeurs Web à mieux comprendre le processus de sécurisation des applications Web et d'aider les enseignants/étudiants à enseigner/apprendre dans un environnement de classe. Application Web sécurité. L'objectif de DVWA est de mettre en pratique certaines des vulnérabilités Web les plus courantes via une interface simple et directe, avec différents degrés de difficulté. Veuillez noter que ce logiciel

Version Mac de WebStorm

Version Mac de WebStorm

Outils de développement JavaScript utiles

Télécharger la version Mac de l'éditeur Atom

Télécharger la version Mac de l'éditeur Atom

L'éditeur open source le plus populaire

Version crackée d'EditPlus en chinois

Version crackée d'EditPlus en chinois

Petite taille, coloration syntaxique, ne prend pas en charge la fonction d'invite de code

MinGW - GNU minimaliste pour Windows

MinGW - GNU minimaliste pour Windows

Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.