我在项目中创建了一堆组件,每个组件都在不同的线程中运行
他们将通过queue.Queue
进行沟通。我想定义所有不同的队列,这是扩展queue.Queue
的类。它们中的每一个都是单例对象,因此不同的组件可以只导入该类,并获取实例。
我将所有内容都放在一个文件中:
from queue import Queue
class QueueAudio(Queue):
def __new__(cls, *args, **kwargs):
"""
Singleton Queue
"""
if '_inst' not in vars(cls):
cls._inst = object.__new__(cls, *args, **kwargs)
print('Creating {}'.format(cls.__name__))
return cls._inst
class AudioInput(object):
def __init__(self):
self.queue = QueueAudio()
print(self.queue)
def run(self):
self.queue.put('Input Audio')
class Interpretor(object):
def __init__(self):
self.queue = QueueAudio()
print(self.queue)
def run(self):
print(self.queue.get())
audio = AudioInput()
audio.run()
interpretor = Interpretor()
interpretor.run()
在两个组件(AudioInput
和Interpretor
)的构造函数中,我打印对象,以确保它们是相同的。
AudioInput
在队列中放入一个字符串,Interpretor
读取它。但是,Interpretor
中的队列始终为空,使程序永远挂起。
这是该计划的输出:
Creating QueueAudio
<__main__.QueueAudio object at 0x103234c18>
<__main__.QueueAudio object at 0x103234c18>
答案 0 :(得分:2)
我通过使用另一种方法将我的类定义为单例来解决我的问题:
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class QueueAudio(Queue, metaclass=Singleton):
pass
答案 1 :(得分:2)
这里发生的事情是,在__new__
函数返回队列对象后,python会在其上隐式调用__init__
。这将重置队列,并删除您之前添加的任何项目。
如果
__new__()
返回cls的实例,则返回新实例__init__()
方法将被调用[...]
一步一步,这就是:
audio = AudioInput() # creates an empty queue
audio.run() # adds a value to the queue
interpretor = Interpretor() # implicit call to Queue.__init__ resets queue
interpretor.run() # queue is empty, call blocks
使用__new__
实现单例时,这是一个常见问题。您可以通过使用元类或使用不同的函数来获取队列单例来解决此问题:
class QueueAudio(Queue):
@classmethod
def new(cls):
if '_inst' not in vars(cls):
cls._inst = cls()
print('Creating {}'.format(cls.__name__))
return cls._inst
# create a queue instance with "QueueAudio.new()"
答案 2 :(得分:0)
嗨,您可以按照本例实现单例队列
创建一个单例装饰器
# singleton.py
def singleton(class_):
instances = {}
def getinstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getinstance
知道用单例装饰定义您的队列类
#singleton_queue.py
import singleton.py
import queue
@singleton
class MySingletonQueue:
def __init__(self, **kwargs):
self.q = queue.Queue()
def put(self, data):
self.q.put(data)
...
我希望对您有帮助