应用环境

  • windows7
  • pycharm2018 profession
  • python3.6
  • django2.0

我们在pycharm 启动django项目时,常常有这么一个命令操作:

  • python manage.py runserver

这里的意思是执行python命令,传入的参数为 manage.py runserver。这两个参数就会被保存到sys.argv 列表中。如下,新建一个demo.py

import sys

print('hello sys.argv')
print(type(sys.argv))
for arg in sys.argv:
print(arg)

在terminal窗口执行 python demo.py runserver  #  循环遍历sys.argv 输出参数

PS:这里解释sys.argv 是因为在manage.py中,会用到。

打开我们的manage.py文件,可以看到,这里调用的是:

  • execute_from_command_line(sys.argv)

可以看到这里传入的就是我们执行python 命令传入的参数(这里是manage.py runserver)。

我们进入到 execute_from_command_line 函数,可以看到的是执行

  • utility.execute()

在execute这个函数中有这么一行代码,读取子命令,也即是读取sys.argv列表中第二个元素runserver,如下图

同时,在execute函数中,我们需要重点关注的是最后这一行代码:

  • self.fetch_command(subcommand).run_from_argv(self.argv)

这里传入的上面的读取的子命令sys.argv[1] 以及self.argv(这里的self.argv 是在构造函数中传入的sys.argv)。

我们进入到 fetch_command 函数,这里最后返回的一个Command class instance 。也就是说 

  • self.fetch_command(subcommand).run_from_argv(self.argv) 

这行代码的意思是 执行返回的实体类必然包含 run_from_argv函数。

在fetch_command中,最终调用的是

  • import_module('%s.management.commands.%s' % (app_name, name))

这里的注释:

Given a command name and an application name, return the Command
class instance. 通过名字返回实例,这里类似net中IL编程:动态导入(动态生成程序集)【这是本篇博文的重点】。
通过:
print('%s.management.commands.%s' % (app_name, name))
我们发现动态导入的实例是:
  • django.contrib.staticfiles.management.commands.runserver

而我们的 import_module 函数最终执行的也是python标准库 importlib下importlib._bootstrap中的gcd_import。如图:

通过上面的分析,我们知道最终执行的是模块:

  • django.contrib.staticfiles.management.commands.runserver

下的run_from_argv 函数。

我们打开runserver.py文件,也确是没有找到该函数,而在其父类中找到:

从上图看出,这个函数最终执行的是execute函数。而在execute中最终执行却又是:

  • output = self.handle(*args, **options)

这里的handle是:

    def handle(self, *args, **options):
"""
The actual logic of the command. Subclasses must implement
this method.
"""
raise NotImplementedError('subclasses of BaseCommand must provide a handle() method')

我们从注释可以知道,这个方法需要由子类实现的,也即最后,最后,最后执行的runserver中handle函数。

分析到这里,已基本很明了,最终执行的是在本地的8000端口启动一个socketserver监听程序。

分析所得:

  • get到python如何进行动态的导入
  • sys.argv 存储了全局中输入参数
  • sys.moduls注册了程序运行已经导入模块
  • if 赋值的优雅写法 subcommand = 'runserver'  if 1== 'condition' else 'hello'

这里一行代码等价于这么写:

if 1=='condition' :

subcommand = 'runserver'

else:

  subcommand = 'hello'

这里一行代码搞定,看起来不错。

希望这篇文字可以帮助到大家。刚接触python,若是有不对的地方,欢迎指出。谢谢。

Django(三)runserver 命令源码分析的更多相关文章

  1. memcached学习笔记——存储命令源码分析下篇

    上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...

  2. memcached学习笔记——存储命令源码分析上篇

    原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...

  3. Java 序列化和反序列化(三)Serializable 源码分析 - 2

    目录 Java 序列化和反序列化(三)Serializable 源码分析 - 2 1. ObjectStreamField 1.1 数据结构 1.2 构造函数 2. ObjectStreamClass ...

  4. debug:am、cmd命令源码分析

    debug:am.cmd命令源码分析 目录 debug:am.cmd命令源码分析 am命令的实现 手机里的am am.jar cmd命令的实现 手机里的cmd cmd activity cmd.cpp ...

  5. TiDB show processlist命令源码分析

    背景 因为丰巢自去年年底开始在推送平台上尝试了TiDB,最近又要将承接丰巢所有交易的支付平台切到TiDB上.我本人一直没有抽出时间对TiDB的源码进行学习,最近准备开始一系列的学习和分享.由于我本人没 ...

  6. Django之REST framework源码分析

    前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...

  7. Python学习---Django的request.post源码分析

    request.post源码分析: 可以看到传递json后会帮我们dumps处理一次最后一字节形式传递过去

  8. Django rest framework 版本控制(源码分析)

    基于上述分析 #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制 self.initial(request, *args, **kwargs) #2.1处理版本信息 #versi ...

  9. storm shell命令源码分析-shell_submission.clj

    当我们在shell里执行storm shell命令时会调用shell_submission.clj里的main函数.shell_submission.clj如下: shell_submission.c ...

随机推荐

  1. java操作xml文件--修改节点

          上一篇文章我介绍了SAX方法解析XML文件的过程,这篇文章讲解的内容是利用DOM方法修改XML文件的节点内容.       下面依然是首先贴出XML文件: <?xml version ...

  2. spring源码系列(一)sring源码编译 spring源码下载 spring源码阅读

    想对spring框架进行深入的学习一下,看看源代码,提升和沉淀下自己,工欲善其事必先利其器,还是先搭建环境吧. 环境搭建 sping源码之前是svn管理,现在已经迁移到了github中了,新版本基于g ...

  3. mysqldump的几个主要选项探究

    0.前言 本文主要探讨 mysqldump 的几种主要工作方式,并且比较一下和 mk-parralel-dump的一些差异,为备份方式的选择提供更多的帮助. 1.mysqldump 首先来看下 mys ...

  4. J2EE进阶(十一)SSH框架整合常见问题汇总(二)

    org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of cn. ...

  5. 02Framelayout:帧布局

    Framelayout:帧布局        >概念:每个组件都是一帧   当前子组件会覆盖前一个组件     >属性:       android:layout_gravity=&quo ...

  6. Intent的Data和Type和Flag属性-amdroid学习之旅(五十一)

    Data属性介绍 使用Data和Action属性启动系统Activity 代码示例 public class MainActivity extends Activity{ @Override prot ...

  7. 学生信息管理小系统(以XML为存储方式)

    为了更好地应用XML,就写了这个小项目. 下面是我的项目的目录结构 项目思路 dao是Date Access Object 数据访问层,主要是负责操作数据 domain是实体层,类似于bean层,放置 ...

  8. UNIX环境高级编程——线程同步之条件变量以及属性

    条件变量变量也是出自POSIX线程标准,另一种线程同步机制.主要用来等待某个条件的发生.可以用来同步同一进程中的各个线程.当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量来 ...

  9. JAVA内部类_1

    使用内部类的原因: (1)可以访问该类定义所在作用域中的数据,包括私有数据. (2)可以对同一个包中的其它类隐藏起来. (3)当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷. 下面 ...

  10. Red Hat Enterprise Linux 5 64-bit chinese language support config steps

    Red Hat Enterprise Linux 5 64-bit 系统下安装中文语言支持方法 测试环境:Windows2012+Vmvare9.0+Red Hat Enterprise Linux ...