1.threading.local
# coding=utf-8
import time
from threading import local, Thread
"""
每个线程都有一个唯一id
如何自己实现一个local呢? 
    通过一个字典
    {
    id1: {val1:1},
    id2: {val2:2},
    id3: {val3:3},
    }
"""
aaa = local()
# aaa = -1
def task(arg):
    # global aaa
    aaa.value = arg
    time.sleep(1)
    print(aaa.value)
for i in range(10):
    t = Thread(target=task, args=(i, ))
    t.start()
time.sleep(3)
2.自定义
# coding=utf-8
"""
如何自己实现一个local呢?
"""
import time
try:
    from greenlet import getcurrent as get_ident  # 协成对象id
except:
    from thread import get_ident  # 线程对象id
from threading import Thread
from flask import globals  # 下面的代码类似于flask的globals类似的
"""版本1"""
storage = {}
def set(k, v):
    ident = get_ident()
    if ident in storage:
        storage[ident][k] = v
    else:
        storage[ident] = {k: v}
def get(k):
    ident = get_ident()
    return storage[ident].get(k)
"""版本2"""
class Local(object):
    storage = {}
    def set(self, k, v):
        ident = get_ident()
        if ident in storage:
            Local.storage[ident][k] = v
        else:
            Local.storage[ident] = {k: v}
    def get(self, k):
        ident = get_ident()
        return Local.storage[ident].get(k)
"""版本3"""
class Local2(object):
    storage = {}
    def __setattr__(self, k, v):
        ident = get_ident()
        if ident in storage:
            Local.storage[ident][k] = v
        else:
            Local.storage[ident] = {k: v}
    def __getattr__(self, k):
        ident = get_ident()
        return Local.storage[ident].get(k)
"""版本4"""
class Local3(object):
    def __init__(self):
        # self.storage = {}  # 调用__setattr__方法
        object.__setattr__(self, "storage", {})
    def __setattr__(self, k, v):
        ident = get_ident()
        if ident in storage:
            self.storage[ident][k] = v
        else:
            self.storage[ident] = {k: v}
    def __getattr__(self, k):
        ident = get_ident()
        return self.storage[ident].get(k)
"""版本N: 我自己写的乱七八糟"""
class Local9(object):
    def __init__(self):
        pass
    def __setattr__(self, key, value):
        ident = str(get_ident())
        self.__dict__["data"] = self.__dict__.get("data", {})
        if self.__dict__["data"].get(ident) is None:
            self.__dict__["data"][ident] = {}
        self.__dict__["data"][ident][key] = value
    def __getattr__(self, item):
        ident = str(get_ident())
        if self.__dict__["data"].get(ident) and self.__dict__["data"][ident].get(item):
            return self.__dict__["data"][ident].get(item)
        else:
            return None
# s1 = Storage()
# # print(s1.__dict__)
# s1.a = 10
# print(s1.a)
# def task(arg):
#     set("val", arg)
#     time.sleep(1)
#     v = get("val")
#     print(v)
#
#
# for i in range(10):
#     print(storage)
#     t = Thread(target=task, args=(i, ))
#     t.start()