析构函数 实例析构 类析构

#!python
# -*- coding:utf-8 -*-
# 场景:
# 目的:通过单例实现客户端调用sdk时,sdk中的方法对客户端数据的批处理

# 参考:
# {
# Python单例模式(Singleton)的N种实现 - 知乎
# https://zhuanlan.zhihu.com/p/37534850

# 设计模式(Python)-单例模式 - 简书
# https://www.jianshu.com/p/ec6589e02e2f

# http://xiaorui.cc/2016/04/10/python多线程下保持单例模式的实例唯一/

# PythonDecoratorLibrary - Python Wiki
# https://wiki.python.org/moin/PythonDecoratorLibrary

# 3. Data model — Python 3.7.3 documentation
# https://docs.python.org/3/reference/datamodel.html#object.__new__

# 8.10. Queue — A synchronized queue class — Python 2.7.16 documentation
# https://docs.python.org/2/library/queue.html
# The Queue class in this module implements all the required locking semantics.

# 3. Data model — Python 3.7.3 documentation
# https://docs.python.org/3/reference/datamodel.html#specialnames

# 3. Data model — Python 3.7.3 documentation
# https://docs.python.org/3/reference/datamodel.html#object.__del__

# }
# 注意:
# 线程安全
# 实例析构、类的析构

# 需要测试:
# 1、线程安全
# 2、效率

# TODO 类的析构

import threading


def make_synchronized(func):
func.__lock__ = threading.Lock()

def synced_func(*args, **kws):
with func.__lock__:
return func(*args, **kws)

return synced_func


class SdkSingletonBatchHandler(object):
__instance = None
# 存放批处理的队列 批处理方法对其按照先进先出FIFO处理
queue_ = []
queueLength = None
batchHandlerFunc = None
# 队列生存时间
timeToLiveSeconds = 1
__bornTime = 0

@make_synchronized
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__bornTime = time.time()
cls.__instance = object.__new__(cls, *args, **kwargs)
if cls.queueLength is None:
cls.queueLength = 10
if len(cls.queue_) >= cls.queueLength or cls.timeToLiveSeconds < time.time() - cls.__bornTime:
cls.batchHandler(cls.queue_)
cls.queue_ = []
cls.bornTime = time.time()
return cls.__instance

@classmethod
def batchHandler(cls, queue_):
return cls.batchHandlerFunc


import time


def bizFuncNotBatch(param):
time.sleep(0.02)
print "do sth" + str(param)


def bizFuncBatch(param):
def batchHandler(paramList):
for i in paramList:
pass
time.sleep(0.02)
print "do sth" + str(paramList)

s = SdkSingletonBatchHandler()
s.__class__.queueLength = 100
s.__class__.batchHandlerFunc = batchHandler
s.queue_.append(param)
print "do sth Batch"
# return 测试所需对象id
return s


# 测试
# 线程安全

def testThreadSafeWorker():
s1 = bizFuncBatch("param")
s2 = bizFuncBatch("param")
print "id1={},id2={}".format(id(s1), id(s2))


task = []
for i in range(300):
t = threading.Thread(target=testThreadSafeWorker())
task.append(t)
for i in task:
i.start()
for i in task:
i.join()

# 测试
# 效率

data = [{'i': i, 'v': "value"} for i in range(1000)]
consoleInfo = []
consoleInfo.append("notBatch:Start:" + time.ctime())
for i in data:
bizFuncNotBatch(i)
consoleInfo.append("notBatch:End:" + time.ctime())
consoleInfo.append("Batch:Start:" + time.ctime())
for i in data:
bizFuncBatch(i)
consoleInfo.append("Batch:End:" + time.ctime())
for i in consoleInfo:
print i
class TestClassDel(object):
__instance = None

def __init__(self):
print("init")

def __new__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = object.__new__(cls, *args, **kwargs)
return cls.__instance

def __del__(self):
print(1)

s1 = TestClassDel()
s2 = TestClassDel()
del s1
del s2


init
init
1

Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32

class TestClassDel(object):
__instance = None

def __init__(self):
print "init"

def __new__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = object.__new__(cls, *args, **kwargs)
return cls.__instance

def __del__(self):
print 1

s1 = TestClassDel()
s2 = TestClassDel()
del s1
del s2


Python 2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)] on win32

init
init

 没有打印1

 注意以上为单例模式 

class TestClassDel(object):
__instance = None

def __init__(self):
print "init"

def __new__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = object.__new__(cls, *args, **kwargs)
return cls.__instance

def __del__(self):
print 1

s1 = TestClassDel()
s2 = TestClassDel()
del s1
del s2

class T():
def __call__(self, *args, **kwargs):
print 1
d=T().__call__()


打印1

受此启发

【注意 目标环境为python2.7.5】


猜你喜欢

转载自www.cnblogs.com/yuanjiangw/p/11004727.html