python设定未来的状态

发布于 2025-01-26 02:42:35 字数 1969 浏览 3 评论 0原文

设定未来的状态以通过论点是不好的做法吗? 专门使用future.q = q在回调中使用q

from threading import Thread
from threading import RLock
from threading import current_thread
from concurrent.futures import Future
import time
import random

class NonBlockingQueue:

    def __init__(self, max_size):
        self.max_size = max_size
        self.q = []
        self.q_waiting_puts = []
        self.q_waiting_gets = []
        self.lock = RLock()

    def enqueue(self, item):

            future = None
            with self.lock:
                curr_size = len(self.q)

                # queue is full so create a future for a put
                # request
                if curr_size == self.max_size:
                    future = Future()
                    self.q_waiting_puts.append(future)

                else:
                    self.q.append(item)

                    # remember to resolve a pending future for
                    # a get request
                    if len(self.q_waiting_gets) != 0:
                        future_get = self.q_waiting_gets.pop(0)
                        future_get.set_result(self.q.pop(0))

            return future


    def retry_enqueue(future):
        print("\nCallback invoked by thread {0}".format(current_thread().getName()))
        item = future.item
        q = future.q
        new_future = q.enqueue(item)

        if new_future is not None:
            new_future.item = item
            new_future.q = q
            new_future.add_done_callback(retry_enqueue)
        else:
            print("\n{0} successfully added on a retry".format(item))



### MAIN CODE
def producer_thread(q):
    item = 1
    while 1:
        future = q.enqueue(item)
        if future is not None:
            future.item = item
            future.q = q
            future.add_done_callback(retry_enqueue)

        item += 1

        # slow down the producer
        time.sleep(random.randint(1, 3))

Is it bad practice to set the state of future to pass arguments?
Specifically using something like future.q = q to use q in the callback

from threading import Thread
from threading import RLock
from threading import current_thread
from concurrent.futures import Future
import time
import random

class NonBlockingQueue:

    def __init__(self, max_size):
        self.max_size = max_size
        self.q = []
        self.q_waiting_puts = []
        self.q_waiting_gets = []
        self.lock = RLock()

    def enqueue(self, item):

            future = None
            with self.lock:
                curr_size = len(self.q)

                # queue is full so create a future for a put
                # request
                if curr_size == self.max_size:
                    future = Future()
                    self.q_waiting_puts.append(future)

                else:
                    self.q.append(item)

                    # remember to resolve a pending future for
                    # a get request
                    if len(self.q_waiting_gets) != 0:
                        future_get = self.q_waiting_gets.pop(0)
                        future_get.set_result(self.q.pop(0))

            return future


    def retry_enqueue(future):
        print("\nCallback invoked by thread {0}".format(current_thread().getName()))
        item = future.item
        q = future.q
        new_future = q.enqueue(item)

        if new_future is not None:
            new_future.item = item
            new_future.q = q
            new_future.add_done_callback(retry_enqueue)
        else:
            print("\n{0} successfully added on a retry".format(item))



### MAIN CODE
def producer_thread(q):
    item = 1
    while 1:
        future = q.enqueue(item)
        if future is not None:
            future.item = item
            future.q = q
            future.add_done_callback(retry_enqueue)

        item += 1

        # slow down the producer
        time.sleep(random.randint(1, 3))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纵山崖 2025-02-02 02:42:36

传递这样的论点不是一个好主意。

原因是,将来(无双关)可能会禁止在Future对象上设置自定义属性,这将破坏您的代码。

更好的解决方案是使用 functials.partial <或lambda将额外的参数传递给回调。

首先,接受q作为retry_enqueue函数的参数:


def retry_enqueue(future, q): # accept 'q' argument
    ...

示例使用function

import functools

future.add_done_callback(functools.partial(retry_enqueue, q=q))

示例使用lambda

future.add_done_callback(lambda future: retry_enqueue(future, q))

It is not a good idea to pass around arguments like this.

The reason is that in future (no pun), they could just disallow setting custom attributes on the Future object, which will break your code.

Better solution is to use functools.partial or lambda to pass extra arguments to the callback.

First, accept q as an argument in the retry_enqueue function:


def retry_enqueue(future, q): # accept 'q' argument
    ...

Example using functools.partial:

import functools

future.add_done_callback(functools.partial(retry_enqueue, q=q))

Example using lambda:

future.add_done_callback(lambda future: retry_enqueue(future, q))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文