基于django 中的settings实现原理,实现自己项目配置文件的可插拔式设计

##首先说一下django中settings.py中的实现原理
'''
应该明确一点,django暴露给用户一个自定义配置的文件,即settings.py,用户配置了就是优先使用用户配置的,否则就使用默认的(from django.conf import global_settings) 同时配置文件中的变量名必须是大写的才能生效(显然,内部实现原理一定有判断是否大写)
'''
'''
其次是它的原理,通过from django.conf import settings 进入源码发现,是通过实例化生成一个LazySettings对象(这里面用到了单例模式,下面会详细介绍),再进源码,看到过程如下: 1.先通过环境变量名,拿到manage.py文件中一启动就写进大字典(相当于一个环境变量的全集合)里的settings文件名(字符串形式的)
2.先判断环境变量是否为空,空的话就抛异常,否则进入settings类中执行
3.执行过程就是用到dir,先循环global_settings中的各种属性方法,然后把其中大写的变量名(字符串)筛选出来,再通过反射的方式先从global_settings中取出值,再setattr到当前对象中
4.然后又通过importlib导入暴露给用户的settings文件,得到对象,同样的道理,先循环取出文件里的属性和方法,再判断是大写就反射取值
5.多了一步就是是否按格式写了(必须是元组或者列表)
6.然后反射设置值,这样,有的话就覆盖,没有就用默认的。 ''' ##然后讲一下用到到几个技术点: ''' 1.单例模式:settings本质就是实例化产生一个对象,但是每次运行都要开辟内存空间存放环境配置太耗资源了,就想到通过实例化一次settings对象,下次用的时候直接导入模块就好了。 2.dir:目的是把对象中的属性和方法全部取出来,列表的形式展示。扩展:dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。 3.反射:主要的语句就是setattr(self, a, getattr(b, c)), 意思就是,先通过c字符串在b对象中取出对应的值,然后把该值赋值给当前对象的a方法或者属性,即self.a = getattr(b,c). 反射主要用在通过字符串判断、取值、设置及删除对象中的方法或者属性。 4.importlib.import_module('settings') == import settings 前者是动态导入,可以根据前一句得到的字符串进行导入,常用场景是希望从配置文件等地获取要被动态加载的module,但配置项通常为字符串类型,无法用import加载。 具体见页尾连接
''' ## 最后思路讲完了,话不多说,直接上代码
'''
还是要先说两句,先设置全局变量,给个启动文件,然后再暴露一个配置文件让用户写。
''' #conf
#里面有暴露给用户的settings.py NAME = "我是暴露给用户的自定义配置" #lib(全局变量就在这里)
## conf(是一个包) ### __init__.py
'''
导入一个模块时,会执行这个模块的代码,申请内存空间,把变量放到内存空间中,导入这个包,会执行__init__中的代码
''' import os
import importlib
from lib.conf import global_settings class Settings(object):
def __init__(self):
for setting in dir(global_settings):
if setting.isupper():
k = setting
v = getattr(global_settings,setting)
setattr(self,k,v)
# 从全局的大字典中获取到暴露给用户的配置文件字符串路径
mod = os.environ.get('xxx')
# mod = 'conf.settings'
module = importlib.import_module(mod)
"""
from conf import settings
module 》》》 settings
"""
for setting in dir(module):
if setting.isupper():
k = setting
v = getattr(module,setting)
setattr(self,k,v) # 循环获取默认的配置文件中所有的大写配置
# 利用setattr给对象不停的设置键值对
# 再循环获取暴露给用户的自定义配置文件中所有的大写的配置
# 再利用setattr给对象不停的设置键值对 settings = Settings() ### global_settings.py NAME = '我是系统默认的全局配置' #start.py import os
import sys BASE_DIR = os.path.dirname(__file__)
sys.path.append(BASE_DIR) os.environ.setdefault('xxx','conf.settings')
from lib.conf import settings
print(settings.NAME) ## 运行后会打印 "我是暴露给用户的自定义配置"

importlib动态导入模块

django settings实现原理及自定义项目settings配置的更多相关文章

  1. django之创建第8个项目-数据库配置及同步研究

    1.sqlitestudio-2.1.5数据库可视化工具--百度云盘下载 2.编写C:\djangoweb\helloworld\blog\models.py文件 # Create your mode ...

  2. django之创建第7-2个项目-url配置分离

    1.urls.PY分离 # -*- coding: UTF-8 -*- from django.conf.urls import patterns, include, url # Uncomment ...

  3. django之创建第7个项目-url配置

    1.配置urls.py from django.conf.urls import patterns, include, url #Uncomment the next two lines to ena ...

  4. django之创建第7-1个项目-url配置高级

    修改urls.PY文件 # -*- coding: UTF-8 -*- from django.conf.urls import patterns, include, url # Uncomment ...

  5. 【SpringBoot1.x】SpringBoot1.x 启动配置原理 和 自定义starter

    SpringBoot1.x 启动配置原理 和 自定义starter 启动配置原理 本节源码 启动过程主要为: new SpringApplication(sources) 创建 SpringAppli ...

  6. django项目settings.py的基础配置

    一个新的django项目初始需要配置settings.py文件: 1. 项目路径配置 新建一个apps文件夹,把所有的项目都放在apps文件夹下,比如apps下有一个message项目,如果不进行此项 ...

  7. day 61 Django part-1 django的安装,以及初学者三件套(以及settings中的mysql配置)

    我们的django到底是什么东西呢? 我们的代码都是在后台写的,包括我们的pycharm都是属于后台的工具,但是我们的后端开发说到底是需要开发完了之后拿到用户面前的,让我们的用户看到我们的东西,首先要 ...

  8. django 之csrf、auth模块及settings源码、插拔式设计

    目录 基于django中间件拷贝思想 跨站请求伪造简介 跨站请求伪造解决思路 方式1:form表单发post请求解决方法 方式2:ajax发post请求解决方法 csrf相关的两个装饰器 csrf装饰 ...

  9. Django框架09 /ajax、crsf、settings导入

    Django框架09 /ajax.crsf.settings导入 目录 Django框架09 /ajax.crsf.settings导入 1. ajax概述 2. ajax应用 3. ajax上传文件 ...

随机推荐

  1. 使用threaddump-analyzer 快速查看jvm thread 状态信息

    日常开发中,我们可以需要通过thread dump 查看线程信息,比如锁,spotify 团队提供了一个web 界面,很方便 以下是简单使用,同时添加了docker 支持 添加docker 支持 cl ...

  2. AGC008E Next or Nextnext(组合计数,神奇思路)

    神仙题. 排列计数,一种常见的做法是 \(i\) 向 \(p_i\) 连边. 然而这里这个就逼迫我们只能从 \(i\) 向 \(a_i\) 连边. 不过没关系,考虑从 \(i\) 向 \(p_i\) ...

  3. Unity Profiler 记录

    版本 Unity 2018.4.6f1 空包 development build 魅蓝 note3 OPPO R9 VIVO x9 华为 P8 青春版 小米 8 SE iphone se Other ...

  4. tsar使用说明

    常用命令    tsar --nginx --live -i 1  查询1秒的状态每秒采样一次 系统模块 cpu 字段含义 user: 表示CPU执行用户进程的时间,通常期望用户空间CPU越高越好. ...

  5. Python连载22-调试&单元测试

    一.调试技术 (1)调试流程​:单元测试->集成测试->交测试部 (2)分类:i.静态调试(说白了就是看代码,看看有没有错):ii.动态测试 1.pdb调试 ​相关连接:https://b ...

  6. axios 源码解析(中) 代码结构

    axios现在最新的版本的是v0.19.0,本节我们来分析一下它的实现源码,首先通过 gitHub地址获取到它的源代码,地址:https://github.com/axios/axios/tree/v ...

  7. Mysql 查询表字段数量

    select count(*) from information_schema.`COLUMNS` where TABLE_SCHEMA='dbName' -- 数据库名 and TABLE_NAME ...

  8. 【UOJ#60】【UR #5】怎样提高智商

    [UOJ#60][UR #5]怎样提高智商 题面 UOJ 题解 首先猜猜答案是\(4*3^{n-1}\).即前面的选啥都行,后面的搞搞就行了. 而打表(看题解),可以知道答案就是这个,并且每个问题都是 ...

  9. 【深度学习】计算机视觉中的 Single-Scale 和 Multi-Scale

    Single-Scale:是指把一张图片送到 CNN : Multi-Scale:一般会送到 CNN 十张图片:比如高宽是 256 Χ 256 的图片,Multi-Scale会在它的四个角以及中心裁剪 ...

  10. C#使用SharpZipLib创建压缩文件,并指定压缩文件夹路径(解决SharpZipLib压缩长路径显示问题)

    在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题.比如,压缩当前程序目录下的某个文件夹(D:\cx\code\program\bin\debug ...