前后端通信传输格式,常见单例模式
一.request请求
request.post只能解析 application/x-www-form-urlencoded,form表单不写enctype默认contentType就是urlencoded
<form class="form-horizontal" method="post" autocomplete="off" novalidate enctype="application/x-www-form-urlencoded">
但是当我们用ajax传json格式的数据的时候,就需要手动设置contentType
$.ajax({ url: "/pcgetcaptcha/=" + (new Date()).getTime(), // 加随机数防止缓存 type: "post", dataType: "json", success: function (data) { consolo.log(data) })
view视图处理
import json
def index1(request):
if request.method == 'POST':
print(request.POST)
print(request.body)
d = json.loads(request.body.decode('utf8'))
当然我们传输的json格式的数据如果很小,也可以这样处理
$.ajax({ url: "/pcgetcaptcha/=" + (new Date()).getTime(), // 加随机数防止缓存 type: "post", data: {xxx:Json.stringify({a:1,b:2})}, success: function (data) { consolo.log(data) }) 这样就可以用默认的contenType:urlencoded来传送,也可以用request.post接收了 def index(request): if request.method == 'POST': json_str = request.POST.get('xxx')
二.单例模式
(1)使用 __new__
为了使类只能出现一个实例,我们可以使用 __new__
来控制实例的创建过程,代码如下:
class Singleton(object): _instance = None def __new__(cls, *args, **kw): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) return cls._instance class MyClass(Singleton): a = 1
在上面的代码中,我们将类的实例和一个类变量 _instance
关联起来,如果 cls._instance
为 None 则创建实例,否则直接返回 cls._instance
。
执行:
>>> one = MyClass() >>> two = MyClass() >>> one == two True >>> one is two True >>> id(one), id(two) (4303862602, 4303862602)
(2)使用模块
Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc
文件,当第二次导入时,就会直接加载 .pyc
文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了
# mysingleton.py class My_Singleton(object): def foo(self): pass my_singleton = My_Singleton()
将上面的代码保存在文件 mysingleton.py
中,然后这样使用:
from mysingleton import my_singleton my_singleton.foo()
在django的admin模块注册的时候我们调用的admin.site就是用的单例模式,源码实现过程如下:
(三)使用装饰器
def Singleton(cls): _instance = {} def _singleton(*args, **kargs): if cls not in _instance: _instance[cls] = cls(*args, **kargs) return _instance[cls] return _singleton @Singleton class A(object): a = 1 def __init__(self, x=0): self.x = x a1 = A(2) a2 = A(3)
(四)使用类
一般情况用以下就可以实现单例:
class Singleton(object): def __init__(self): pass @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance
但是多线程就不能保证单例,需要进行以下修改:
import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance def task(arg): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start() time.sleep(20) obj = Singleton.instance() print(obj)
注意:这种方式实现的单例模式,使用时会有限制,以后实例化必须通过obj = Singleton.instance()
如果用 obj=Singleton() ,这种方式得到的不是单例
(5)基于metaclass方式实现
首先我们必须了解以下知识:
1.类由type创建,创建类时,type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)
2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法
单例实现代码如下:
import threading class SingletonType(type): _instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super(SingletonType,cls).__call__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name obj1 = Foo('name') obj2 = Foo('name') print(obj1,obj2)