python:python类中列表或dict上的信号量保护
我的代码 使用上面的代码,我试图在调用python:python类中列表或dict上的信号量保护,python,Python,我的代码 使用上面的代码,我试图在调用save\u to\u disk时使用信号量来保护我的x和y。但是当我调用my_class.x['a']=123时,my_class.\uuuuuu setattr\uuuu不会被调用。因此我的x不受保护 我有两个问题: 当我调用my_class.x['a']=123调用哪个python函数时 如何仅在my_类中保护我的x和y,而不保护全局 列表和目录;我的x和y可能还有一个列表或dict 更新: 我想为上面的随机代码更新一些概念。 我想创建一个类似AI
save\u to\u disk
时使用信号量来保护我的x
和y
。但是当我调用my_class.x['a']=123
时,my_class.\uuuuuu setattr\uuuu
不会被调用。因此我的x
不受保护
我有两个问题:
- 当我调用
调用哪个python函数时my_class.x['a']=123
- 如何仅在
中保护我的my_类
和x
,而不保护全局y
和列表
;我的目录
和x
可能还有一个y
或列表
dict
- 创建继承
和dict
的list
类来重写
和{}
,但需要我更新所有[]
和{}
。这不是效率[]
- 目前我正在尝试创建一个读/写信号量,然后覆盖
,dict()。\uuuu setitem\uuuu
,等等。但我不知道会发生什么list.append
def\uu getattribute\uu(self,item):
关于你的想法
我想创建一个类似AI的内核。人工智能必须同时做2项工作。一是收集我提供的所有信息。第二,当达到阈值时,它必须将信息保存到磁盘(我不希望它杀死我的RAM)
问题是因为两个线程想要共享同一个变量,对吗
如果是这样的话,也许您可以尝试一次只让一个线程工作,那么就不用担心资源会发生变化
例如:
class myclass:
def __init__(self):
self.x = {}
self.y = []
self.semaphore = threading.Semaphore()
def __semaphore(func):
def wrapper(**args. *kw):
args[0].__sync_semaphore.acquire()
ret = func(*args, **kw)
args[0].__sync_semaphore.release()
return ret
return wrapper
@__semaphore
def __setattr__(self, name, value):
super().__setattr__(name, value)
@__semaphore
def save_to_disk(self):
""" access to my_class.x and my_class.y """
my_class = myclass()
my_class.x['a'] = 123
如果这对你仍然毫无用处,我将删除答案。如果您有任何问题,请告诉我,谢谢。Q1
当我调用我的_class.x['a']=123时,调用哪个python函数
首先调用def\uu getattribute\uu(self,item):
关于你的想法
我想创建一个类似AI的内核。人工智能必须同时做2项工作。一是收集我提供的所有信息。第二,当达到阈值时,它必须将信息保存到磁盘(我不希望它杀死我的RAM)
问题是因为两个线程想要共享同一个变量,对吗
如果是这样的话,也许您可以尝试一次只让一个线程工作,那么就不用担心资源会发生变化
例如:
class myclass:
def __init__(self):
self.x = {}
self.y = []
self.semaphore = threading.Semaphore()
def __semaphore(func):
def wrapper(**args. *kw):
args[0].__sync_semaphore.acquire()
ret = func(*args, **kw)
args[0].__sync_semaphore.release()
return ret
return wrapper
@__semaphore
def __setattr__(self, name, value):
super().__setattr__(name, value)
@__semaphore
def save_to_disk(self):
""" access to my_class.x and my_class.y """
my_class = myclass()
my_class.x['a'] = 123
如果这对你仍然毫无用处,我将删除答案。如果您有任何问题,请告诉我,谢谢。TLDR:仅在
myclass
方法上执行此操作是没有用的,因为不仅涉及myclass
my_class.x['a']=123
相当于:
import asyncio
import numpy as np
from time import time
async def take_data(num_of_data):
count = 0
t_s = time()
while 1:
if count == num_of_data:
break
data = await collect_data()
cost_time = time() - t_s
yield list(data), dict(time=cost_time)
t_s = time()
count += 1
async def collect_data():
while 1:
data = np.random.normal(1, 1, (10,))
threshold = all(data > 1.6)
if threshold:
break
return data
async def ai_process():
async for res_list, res_dict in take_data(5):
print(res_dict['time'])
# save_to_desktop()
...
def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([ai_process()]))
loop.close()
if __name__ == '__main__':
main()
请注意调用x.\uuuu setitem.\uuu
时,对my\u类.\uuuu getattr\uuuu
的调用是如何完成的。因此,my_class
方法内部的任何同步都属于错误的范围
通过仅在同步块中对类字段进行访问,可以保护类字段不受并发访问 Python同步块的基本方法是
with
语句,例如。要简化自定义块的创建,请使用单个生成器(而不是两种方法)。最后是一种新的方法,例如同步
def set_x_a(obj: myclass, value):
x = obj.__getattr__('x') # fetch `x` via `myclass` method
x.__setitem__('a', value) # set `'a'` via `type(x)` method
set_x_a(my_class, 123)
重要的变化是,dict
属性不再直接公开。它仅在持有锁的情况下可用
您可以将此模式扩展到其他属性,并改进属性的保护。例如,您可以
生成的副本或self.\ux
,并在块的末尾显式更新内部状态,从而使外部引用的效果在之后失效。TLDR:仅对myclass
方法执行此操作是没有用的,因为不仅涉及myclass
my_class.x['a']=123
相当于:
import asyncio
import numpy as np
from time import time
async def take_data(num_of_data):
count = 0
t_s = time()
while 1:
if count == num_of_data:
break
data = await collect_data()
cost_time = time() - t_s
yield list(data), dict(time=cost_time)
t_s = time()
count += 1
async def collect_data():
while 1:
data = np.random.normal(1, 1, (10,))
threshold = all(data > 1.6)
if threshold:
break
return data
async def ai_process():
async for res_list, res_dict in take_data(5):
print(res_dict['time'])
# save_to_desktop()
...
def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([ai_process()]))
loop.close()
if __name__ == '__main__':
main()
请注意调用x.\uuuu setitem.\uuu
时,对my\u类.\uuuu getattr\uuuu
的调用是如何完成的。因此,my_class
方法内部的任何同步都属于错误的范围
通过仅在同步块中对类字段进行访问,可以保护类字段不受并发访问
Python同步块的基本方法是with
语句,例如。要简化自定义块的创建,请使用单个生成器(而不是两种方法)。最后是一种新的方法,例如同步
def set_x_a(obj: myclass, value):
x = obj.__getattr__('x') # fetch `x` via `myclass` method
x.__setitem__('a', value) # set `'a'` via `type(x)` method
set_x_a(my_class, 123)
重要的变化是,dict
属性不再直接公开。它仅在持有锁的情况下可用
您可以将此模式扩展到其他属性,并改进属性的保护。例如,您可以生成的副本或self.\ux
,并在块的末尾显式更新内部状态,从而使外部引用的效果在之后失效。A1:您不能运行myu class.x['a']=123
,因为myu类是一个类,而且它没有x.A2属性:请参阅属性装饰器
可能对您有帮助,我知道@property decorator,但如果不是我错了,该装饰器对列表没有帮助,我认为这涉及实际问题。如果你想得到更好的建议,我建议你把真正的问题提出来。我看不出这样做的动机