• 1、单例模式
  • 2、admin源码解析
  • 3、注册源码流程图
  • 3、admin之url方法的使用
  • 4、admin源码之url设计
  • 5、设计url源码流程
  • 6、总结

1、单例模式

https://www.cnblogs.com/yuanchenqi/articles/8323452.html

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。一个类只能实例化出一个对象,只开辟一块内存空间配置如果是一个类的话,那么配置应该就实例化一个对象,谁改了配置信息,别的调用应该是都会这个修改了以后的,大家公用这一个单例模式对象。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,这样会导致一个系统而配置不统一,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序

(python原生单例)

  • 使用模块

  • 使用 __new__

1. 使用 __new__

为了使类只能出现一个实例,我们可以使用 __new__ 来控制实例的创建过程,代码如下:

    class  Singleton(object):
_instance=None
def __new__(cls,*args,**kwargs):
if not cls._instance:
cls._instance=super(Singleton,cls).__new__(cls,*args,**kwargs)
return cls._instance class MyClass(Singleton)
a=1

mc1=MyClass(Singleton)
第一次的时候执行new方法,去父类中找,父类中第一次,if not None,所以拿到了给变量(cls._instance)赋了一个值,也就是这个实例化对象,并把它返回。

mc2=MyClass(Singleton)
第二次去实例化的时候,因为_instance已经有值了,所以直接反回了cls._instance,这样
拿到的还是上一个实例化的。

print(id(mc1))==print(id(mc2)) === >TRUE

2. 使用模块

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:

python的模块加载只执行一次。

第一个文件mysingleton:

class My_singleton():
def foo(self):
print("foo...") my_singleton=My_singleton()

在第二个文件导入上边的文件:

    第二个文件main:
from mysingleton import my_singleton
#第一次导入了这个文件的实例化的对象 my_singleton.foo()
#执行了foo方法,输出了foo... print(id(my_singleton))
#打印ID #插一点: 这两个ID也一样,无论怎么重命名也只是导入一次from mysingleton import my_singleton as my_singleton_new
print(id(my_singleton_new))
print(id(my_singleton))
 import func
#导入func,相当于把下面代码拿过来了 '''
from mysingleton import my_singleton def bar():
print(id(my_singleton))
''' #当执bar的时候,发现又导入了一遍(from mysingleton import my_singleton),
#所以还使用原来的实例化对象,所以2个ID值是相同的。
func.bar()
思考三:
如果把main中换成,如下:
from mysingleton import my_singleton,My_singleton
ms1=My_singleton() from mysingleton import my_singleton,My_singleton
ms2=My_singleton() print(id(ms1))
print(id(ms2))
虽然导入了2次,但是生成的是2个新的实例化对象,只有my_signleton是单例对象。(这里注意一下)

2、admin源码解析

<1> 循环加载执行所有已经注册的app中的admin.py文件

Admin的实现流程:
1.启动部分:

#扫描执行每一个APP下的admin.py文件。
def autodiscover():
  autodiscover_modules('admin',register_to=site)

<2> 注册

#admin.py

class BookAdmin(admin.ModelAdmin):
list_display = ("title",'publishDate', 'price')
admin.site.register(Book, BookAdmin)
admin.site.register(Publish)

<3> admin.site

site=AdminSite()
这个site就是这一个单例对象。(所有的都取公用这一个实例化对象)
admin.site.register(Book)

<4> 注册过程

class AdminSite(object):
def __init__(self,name='admin'):
self._registry={} #admin_class_objlass=None 就是样式类,不传默认使用原始的
def register(self,model,admin_class=None,**options):
if not admin_class:
admin_class=ModelAdmin
#第二个参数如果传的话,这个就不成立,也就是不适用他原本的配置类
self._registry[model]=admin_class(model,self) #{Book:ModelAdmin(Book)}

<4.5>源码解析

 1.admin.site.register(Book):
self._registry[model]=admin_class(model,self) #{Book:ModelAdmin(Book)} 2.admin.site.register(Publish):
self._registry[model]=admin_class(model,self) #{Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)} 3.admin.site.register(Author,AuthorConfig):
#这个里面的自定义样式也继承的modelAdmin类,只是增加了一些样式。
self._registry[model]=admin_class(model,self) #{Book:ModelAdmin(Book),Publish:ModelAdmin(Publish),Author,AuthorConfig(Author)} # 键就是model,如果写个Book,那么书就是键。(以模型类变量为键)类的实例对象为值。
<class 'app01.models.Book'>:<app01.admin.BookConfig object at 0x000000ID58>

这里关于面向对象补充一点:

class Animal(object):
hobby="girl" def run(self):
print(self.hobby)
print(runing...) class Dog(Animal):
hobby="吃鸡"
def __init__(self,name): liwenzhou = Dog("liwenzhou")
liwenzhou.run()
jinxin=Animal()
jinxin.run() #这里注意的是liwenzhou调用run方法是继承自上面动物类的,动物类的self这时候是liwenzhou,因为dog类本身有hobby属性,所以输出的是
吃鸡 ,runing...
而jinxin是直接动物类的实例化对象,这样的话,self就是本身,也就代表hobby是girl 。
girl , runing...
**关于注册的时候注意的一点:
所以自定义样式类继承ModelAdmin,找的话先从自身开始找类变量,如果自身的类变量没有才去父类中找到类变量继承。就和上面那个动物和狗的继承例子类似。

<5> admin的URL配置

urlpatterns = [
url(r'^admin/', admin.site.urls),
]
 
class AdminSite(object):

     def get_urls(self):
from django.conf.urls import url, include urlpatterns = [] # Add in each model's views, and create a list of valid URLS for the
# app_index
valid_app_labels = []
for model, model_admin in self._registry.items():
urlpatterns += [
url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
]
if model._meta.app_label not in valid_app_labels:
valid_app_labels.append(model._meta.app_label) return urlpatterns @property
def urls(self):
return self.get_urls(), 'admin', self.name
 

<6>  url()方法的扩展应用

 
from django.shortcuts import HttpResponse
def test01(request):
return HttpResponse("test01") def test02(request):
return HttpResponse("test02") urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^yuan/', ([
url(r'^test01/', test01),
url(r'^test02/', test02), ],None,None)), ]
 

扩展优化

 
from django.conf.urls import url,include
from django.contrib import admin from django.shortcuts import HttpResponse def change_list_view(request):
return HttpResponse("change_list_view")
def add_view(request):
return HttpResponse("add_view")
def delete_view(request):
return HttpResponse("delete_view")
def change_view(request):
return HttpResponse("change_view") def get_urls(): temp=[
url(r"^$".format(app_name,model_name),change_list_view),
url(r"^add/$".format(app_name,model_name),add_view),
url(r"^\d+/del/$".format(app_name,model_name),delete_view),
url(r"^\d+/change/$".format(app_name,model_name),change_view),
] return temp url_list=[] for model_class,obj in admin.site._registry.items(): model_name=model_class._meta.model_name
app_name=model_class._meta.app_label # temp=url(r"{0}/{1}/".format(app_name,model_name),(get_urls(),None,None))
temp=url(r"{0}/{1}/".format(app_name,model_name),include(get_urls()))
url_list.append(temp) urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^yuan/', (url_list,None,None)),
]
 
这里有一个点就是url完成了分发,但是所有的表走的都是同一个增加函数,所有的表都是同一个删除,查看,修改函数,这显然是不合理的,怎么才能让不同的表走各自对应
的增删改查表函数呢?
 
 

3、注册源码流程图

{<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x00000085C948DD68>}
{<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x00000085C948DD68>,
<class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x00000085C94C87F0>}

 
{<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000008CD0BCCCF8>}
{<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000008CD0BCCCF8>,
<class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000008CD0C0EDA0>}
{<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000008CD0BCCCF8>,
<class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000008CD0C0EDA0>,
<class 'app02.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000008CD0C0EF28>}
 

3、admin之url方法的使用

情况1:url(r'^book/', views.book),  # book(request)

  情况2 分发:

 
url(r"^yuan/", ([
url(r'^test01/', ([
url(r'^test04/', test04),
url(r'^test05/', test05),
], None, None)),
url(r'^test02/', test02),
url(r'^test03/', test03),
], None, None)
)
 

code

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse from app01 import views def test01(request): return HttpResponse("test01") def test02(request): return HttpResponse("test02") def test03(request): return HttpResponse("test03") def test01111(request):
return HttpResponse('test01111') def test01333(request):
return HttpResponse('test01333') def test01222(request):
return HttpResponse('test01222') def yuan(request): return HttpResponse("yuan") urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^index/', views.index),
url(r'^book/', views.book), # url(r'^yuan/', yuan), url(r'^yuan/',([
url(r'^test01/',([
url(r'^test01111',test01111),
url(r'^test01111',test01222),
url(r'^test01111',test01333), ],None,None)),
url(r'^test02/',test02),
url(r'^test03/',test03), ],None,None))
]

4、admin源码之url设计

1、 如何通过model类变量获取该模型的字符串名称和该模型所在app的字符串名称:

print("===>", model._meta.model_name)
print("===>", model._meta.app_label)

2、扩展1层url

3、扩展2层url

5、设计url源码流程

6、总结

1、code代码

url.py  设计+注册

"""MRBS URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse from app01 import views def test01(request): return HttpResponse("test01") def test02(request): return HttpResponse("test02") def test03(request): return HttpResponse("test03") def test01111(request):
return HttpResponse('test01111') def test01333(request):
return HttpResponse('test01333') def test01222(request):
return HttpResponse('test01222') def list_view(reuquest):
return HttpResponse("list_view") def add(reuquest):
return HttpResponse("add") def delete(reuquest,id):
return HttpResponse("delete") def change(reuquest,id):
return HttpResponse("change") def get_urls2():
temp = []
temp.append(url(r"^$/",list_view))
temp.append(url(r"^add/",add))
temp.append(url(r"^(\d+)/delete",delete))
temp.append(url(r"^(\d+)/change",change)) return temp def get_urls():
temp = []
# print("_registry", admin.site._registry)
for model,admin_class_obj in admin.site._registry.items():
# print("model",model) # model <class 'app02.models.Book'> "app01" "book"
# print(model._meta.model_name) # "book"
# print(model._meta.app_label) # "app01"
model_name = model._meta.model_name
app_label = model._meta.app_label
temp.append(url(r"%s/%s/"%(app_label,model_name),(get_urls2(),None,None))) return temp urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^index/', views.index),
url(r'^book/', views.book),
url(r'^yuan/', (get_urls(),None,None))
] """
1、url的使用
url(r'^yuan/',([
url(r'^test01/',([
url(r'^test01111',test01111),
url(r'^test01111',test01222),
url(r'^test01111',test01333), ],None,None)),
url(r'^test02/',test02),
url(r'^test03/',test03), ],None,None))
"""

2、知识点2:url()的使用:


情况1:path('book/', views.book), # book(request)
情况2:分发:
path('yuan/',yuan), # yuan
path('yuan/',([],None,None)) # None,None 代表:namespace app(name)
path('yuan/',([path('test01/',test01)],None,None)), # yuan/test01
 
        path('yuan/',([
path('test01/',([
path('test04/',test04), # yuan/test01/test04
path('test05/',test05) # yuan/test01/test05
],None,None)),
path('test02/',test02), # yuan/test02
path('test03/',test03) # yuan/test03
],None,None))
 

3、知识点3:admin源码

    admin源码:

    1.注册 admin.py
from django.contrib import admin class BookConfig(admin.ModelAdmin):
list_display = ['user', 'room']
... admin.site.register(Book,BookConfig) # admin.site 就是 AdminSite()的一个实例化对象(单例)
admin.site.register(UserInfo,UserConfig)
admin.site.register(Room)
 
        class AdminSite():
def __init__(self, name='admin'):
self._registry = {} def register(self, model, admin_class=None):
if not admin_class:
admin_class = ModelAdmin self._registry[model] = admin_class(model, self) ...
...
site = AdminSite()
        所以:按顺序注册后,结果都在 admin.site._registry 字典里面;model为键,admin_class(model, self)为值;
即:Book为键,BookConfig()为值;
UserInfo为键,UserConfig()为值;
Room为键,ModelAdmin()为值; 注意:admin.site._registry 全局的!! 多个app共用!!(startapp02)
 
     print(admin.site._registry)
{<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x000002777731D400>,
<class 'app01.models.Book'>: <app01.admin.BookConfig object at 0x000002777735C470>,
<class 'app01.models.UserInfo'>: <app01.admin.UserConfig object at 0x000002777735C4A8>,
<class 'app01.models.Room'>: <django.contrib.admin.options.ModelAdmin object at 0x000002777735C4E0>,
<class 'app01.models.GF'>: <django.contrib.admin.options.ModelAdmin object at 0x000002777735C518>,
<class 'app02.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x000002777735C438>}
 
    2.设计 url:
注意:
1.
path('yuan/',(get_urls(),None,None)), get_urls()执行返回的就是一个列表
path('yuan/',include(get_urls()))
    def get_urls(self):
temp=[]
for model,stark_class_obj in self._registry.items():
model_name=model._meta.model_name
app_label =model._meta.app_label temp.append(url(r"^%s/%s/"%(app_label,model_name),stark_class_obj.urls2))
return temp
            2.
for model,admin_class_obj in admin.site._registry.items():
print('****',model) # **** <class 'app01.models.Book'> model_name = model._meta.model_name # book
app_label = model._meta.app_label # app01 3.
temp.append(path('%s/%s/'%(app_label,model_name),(get_urls2(),None,None))) 4.
temp.append(path('add/',add))
temp.append(re_path(r'(\d+)/delete/',delete))
temp.append(re_path(r'(\d+)/change/',change))
temp.append(re_path(r'^$',list_view)) 5.
# 24条 url 。。。
# http://127.0.0.1:8020/yuan/app01/book/
# http://127.0.0.1:8020/yuan/app01/userinfo/add/
# http://127.0.0.1:8020/yuan/app01/book/5/delete/
# http://127.0.0.1:8020/yuan/app02/book/
 

单例模式及设计url分发的更多相关文章

  1. 设计url 通过分发的方式 Xadmin_demo

    如 urlpatterns = [ url(r'^Xadmin/',([ url(r'^add/$', views.add) url(r'^delete/$', views.delete) ], No ...

  2. day 82 URL分发

    一 .admin 流程 (1) 启动 autodiscover_modules('admin', register_to=site) (2) 注册 单例模式 admin.site=AdminSite( ...

  3. django url分发,视图,模板回顾

    Django基础轮廓 MTV+controller 一 url分发系统: 1 简单使用 url(r'^articles/2003/$', views.special_case_2003), # spe ...

  4. url分发(二级分发)

    from django.shortcuts import HttpResponsedef test(request): return HttpResponse('test') from django. ...

  5. URL分发(URLConf)

    如果项目中应用太多,都写到顶层的urls.py中,如果个别应用url出问题的话,其他的应用也会受影响,所以我们需要对每个应用下面都写一个urls.py,实现分发 顶层urls.py中写:(属于blog ...

  6. Java 静态static关键字,main函数,对象的初始化过程,对象调用成员,单例模式的设计,静态代码块(6)

    Java 静态static关键字,静态代码块详情参考:static的使用原理讲解http://www.cnblogs.com/itcqx/p/5519464.html main函数: java Mai ...

  7. Django路由配置之子路由include(URL分发)

    子路由include(URL分发) 在一个项目中可能存在多个应用,为了方便区分和管理,在项目的总路由urls.py中会进行路由分发: (1)项目总路由导入from  django.conf.urls  ...

  8. day53:django:URL别名/反向解析&URL分发&命名空间&ORM多表操作修改/查询

    目录 1.URL别名&反向解析 2.URL分发&命名空间 3.ORM多表操作-修改 4.ORM多表操作-查询 4.1 基于对象的跨表查询 4.2 基于双下划线的跨表查询 4.3 聚合查 ...

  9. iOS架构设计-URL缓存

    概览 缓存组件应该说是每个客户端程序必备的核心组件,试想对于每个界面的访问都必须重新请求势必降低用户体验.但是如何处理客户端缓存貌似并没有统一的解决方案,多数开发者选择自行创建数据库直接将服务器端请求 ...

随机推荐

  1. Hibernate 5 入门指南-基于类注解

    首先创建hibernate.cfg.xml配置文件并做简单的配置 <hibernate-configuration>    <session-factory>        & ...

  2. Xmanager power suit 6 最新版注册激活

    Xmanager Power Suit 6.0.0012 最新版注册激活,长期更新 操作步骤 Xmanger Power Suit 官方 其实有两种 .exe 文件,一个是用于试用的,在注册的时候不能 ...

  3. Java运行Jar包内存配置

    java -jar -Xms1024m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M car.jar 说明: 1.堆内存:最小1024M,最大153 ...

  4. 【夯实PHP基础】PHP多进程-- pcntl_fork实现

    本文地址 参考文档 分享提纲: 1. 概述 2.安装(只支持Linux) 3. 代码实验多进程pcntl_fork 4. 具体解释 1. 概述 PHP有个pcntl_fork的函数可以实现多进程,但要 ...

  5. 14.UA池和代理池

    今日概要 scrapy下载中间件 UA池 代理池 今日详情 一.下载中间件 先祭出框架图: 下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - ...

  6. shopkeep/spark Dockerfile示例

    FROM java:openjdk- ENV HADOOP_HOME /opt/spark/hadoop- ENV MESOS_NATIVE_LIBRARY /opt/libmesos-.so ENV ...

  7. centos7下安装docker(23.docker-swarm之如何访问service)

    如何访问service呢? 为了便于分析,我们重新部署web-server 1.删除service 执行命令docker service rm web-server docker service rm ...

  8. 11175-From D to E and Back(思维)

    Problem UVA11175-From D to E and Back Accept: 164  Submit: 607Time Limit: 3000 mSec Problem Descript ...

  9. UVA215-Spreadsheet Calculator(模拟+拓扑排序)

    Problem UVA215-Spreadsheet Calculator Accept:401  Submit:2013 Time Limit: 3000 mSec Problem Descript ...

  10. 小a与黄金街道 (欧拉函数)

    题意:a, b两个人在长度为n的一维数轴上(从1开始).a在1,b在n.每个人以1m/s的速度相向而行,则每一时刻存在坐标x,y,当cgd(n, x)==1,gcd(n, y)==1时,t1=k^x, ...