前后端通信传输格式,常见单例模式

一.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)

 

 
posted @ 2018-09-09 12:59  似水年华梦  阅读(242)  评论(0编辑  收藏  举报