Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python:python类中列表或dict上的信号量保护_Python - Fatal编程技术网

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
不受保护

我有两个问题:

  • 当我调用
    my_class.x['a']=123
    调用哪个python函数时
  • 如何仅在
    my_类
    中保护我的
    x
    y
    ,而不保护全局
    列表
    目录
    ;我的
    x
    y
    可能还有一个
    列表
    dict
更新: 我想为上面的随机代码更新一些概念。 我想创建一个类似AI的内核。人工智能必须同时做2项工作。一是收集我提供的所有信息。第二,当达到阈值时,它必须将信息保存到磁盘(我不希望它杀死我的RAM)

我试图做的事

  • 创建继承
    dict
    list
    类来重写
    {}
    []
    ,但需要我更新所有
    {}
    []
    。这不是效率
  • 目前我正在尝试创建一个读/写信号量,然后覆盖
    dict()。\uuuu setitem\uuuu
    list.append
    ,等等。但我不知道会发生什么
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
如果这对你仍然毫无用处,我将删除答案。如果您有任何问题,请告诉我,谢谢。

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,但如果不是我错了,该装饰器对列表没有帮助,我认为这涉及实际问题。如果你想得到更好的建议,我建议你把真正的问题提出来。我看不出这样做的动机