单例模式的几种方法:
1、利用类的双下__new__方法实现单例模式:
每实例化一个对象都会new一次,每个对象都会新建一个新的内存地址,那么可以自定义new方法实现单例模式,即每创建一个对象都继用实例化的第一个对象的内存地址,不管对哪个对象进行操作,都是操作同一个对象
class Teacher: __new_teacher = False #私有化一个属性 def __init__(self,name,sex): self.name = name self.sex = sex def __new__(cls, *args, **kwargs):#实现了不管如何创建对象,都是返回这个私有属性,这个私有属性一直是第一次实例化的对象 if cls.__new_teacher: #如果私有化属性不为空 return cls.__new_teacher #返回这个属性(对象) else: cls.__new_teacher = object.__new__(cls) #否则就创建一个对象赋值给私有化的属性 return cls.__new_teacher #返回这个属性(对象) aike = Teacher('aike','man') aike1= Teacher('aike','man') print(aike)#内存地址一样 print(aike1)#内存地址一样 aike.name = '艾克' print(aike.name)#艾克 print(aike1.name)#艾克 #打印: <__main__.Teacher object at 0x000001C184484D48> <__main__.Teacher object at 0x000001C184484D48> 艾克 艾克
1、利用python导包特性,实现单例模式
Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。后续导入时,模块中的对象内存地址依然是指向第一次导入时的地址。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
class Person(object): def __init__(self, name, age): self.name = name self.age = age p1 = Person("aike", 9000)
from singleton import p1 print(id(p1)) print(p1.name) p1.name = "Bob" from singleton import p1 print(id(p1)) print(p1.name)
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
这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象
4、执行register方法
admin.site.register(Book, BookAdmin)
admin.site.register(Publish)
class ModelAdmin(BaseModelAdmin):pass def register(self, model_or_iterable, admin_class=None, **options): if not admin_class: admin_class = ModelAdmin # Instantiate the admin class to save in the registry self._registry[model] = admin_class(model, self)
到此,注册结束,然后进行url分发
5、django2.2.10下,admin的URL配置
urlpatterns = [ path('admin/', admin.site.urls), ]
AdminSite类下进行一级分发:
def get_urls(self): from django.urls import include, path, re_path # Since this module gets imported in the application's root package, # it cannot import models from other applications at the module level, # and django.contrib.contenttypes.views imports ContentType. from django.contrib.contenttypes import views as contenttype_views def wrap(view, cacheable=False): def wrapper(*args, **kwargs): return self.admin_view(view, cacheable)(*args, **kwargs) wrapper.admin_site = self return update_wrapper(wrapper, view) # Admin-site-wide views. urlpatterns = [ path('', wrap(self.index), name='index'), path('login/', self.login, name='login'), path('logout/', wrap(self.logout), name='logout'), path('password_change/', wrap(self.password_change, cacheable=True), name='password_change'), path( 'password_change/done/', wrap(self.password_change_done, cacheable=True), name='password_change_done', ), path('jsi18n/', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'), path( 'r/<int:content_type_id>/<path:object_id>/', wrap(contenttype_views.shortcut), name='view_on_site', ), ] # 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 += [ path('%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)), ] # model_admin.urls进行二级分发 if model._meta.app_label not in valid_app_labels: valid_app_labels.append(model._meta.app_label) # If there were ModelAdmins registered, we should have a list of app # labels for which we need to allow access to the app_index view, if valid_app_labels: regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$' urlpatterns += [ re_path(regex, wrap(self.app_index), name='app_list'), ] return urlpatterns @property def urls(self): return self.get_urls(), 'admin', self.name