问题
我一直在尝试创建一个线程安全的SingletonClass作为模块,可以通过导入为模块来重用在其他python脚本中。更像import and use it
作为要使其成为单例的类的元类。
但是,但是当我运行程序时,我陷入了僵局,其他导入模块的类都在等待在他们之前有人用它作为元类来发布。我了解我可能缺少与导入和名称空间相关的大量python基础知识,这就是我无法理解这一点的原因。我之前一般都阅读过以下有关单例的文章,但我认为这个问题与导入有关,而不是其他任何问题。
链接:Creating a singleton in Python
如果有人可以指出这个错误并提供一种可能的方法使其成为可重用的模块,或者提供可以帮助我解决此问题的外部文章的链接,那将是很好的。让我知道我的想法是可行的还是有缺陷的。这确实有助于正确理解基本知识。
下面给出我的文件夹结构和相应的代码。
以下是我的文件夹结构,每个文件中都有相应的代码。
.
├── A.py
├── B.py
├── C.py
└── ThreadSafeSingleton.py
0 directories, 4 files
[代码] >>
ThreadSafeSingleton.py
import threading import logging logger= logging.getLogger(__name__) class ThreadSafeSingletonClass(type): # Taken from: https://stackoverflow.com/a/51897195 :) _instances = {} _singleton_lock = threading.Lock() def __call__(cls, *args, **kwargs): # double-checked locking pattern logger.error("ThreadSafeSingletonClass : Inside __call__ of ThreadSafeSingleton") logger.error("ThreadSafeSingletonClass : Called By"+str(cls)) if cls not in cls._instances: logger.error("ThreadSafeSingletonClass : Trying to get lock") with cls._singleton_lock: logger.error("ThreadSafeSingletonClass : Got lock") if cls not in cls._instances: logger.error("ThreadSafeSingletonClass : Object of type" + str(cls) + " being Created") cls._instances[cls] = super(ThreadSafeSingletonClass, cls).__call__(*args, **kwargs) logger.error("ThreadSafeSingletonClass : Returning created Instance"+str(cls)) return cls._instances[cls]
A.py
import logging from ThreadSafeSingleton import ThreadSafeSingletonClass from B import B logger=logging.getLogger(__name__) logger.setLevel(logging.DEBUG) class A(metaclass = ThreadSafeSingletonClass): def __init__(self): logger.error("A : Inside init of A") logger.error("A : Creating object of B") b=B() logger.error("A: Creating object of A as part of main") A() logger.error("A: Returned back to A now") logger.error("A: Exiting...")
B.py
from ThreadSafeSingleton import ThreadSafeSingletonClass import C import logging logger = logging.getLogger(__name__) class B(metaclass=ThreadSafeSingletonClass): def __init__(self): logger.error("B: Inside Init of B") logger.error("B: Trying to create object of C") c=C.C()
C.py
from ThreadSafeSingleton import ThreadSafeSingletonClass class C(metaclass = ThreadSafeSingletonClass): def __init__(self): logger.error("C: We are at C Object")
[输出
(env) duplex@Test:~/test/Test$ python A.py A: Creating object of A as part of main ThreadSafeSingletonClass : Inside __call__ of ThreadSafeSingleton ThreadSafeSingletonClass : Called By<class '__main__.A'> ThreadSafeSingletonClass : Trying to get lock ThreadSafeSingletonClass : Got lock ThreadSafeSingletonClass : Object of type<class '__main__.A'> being Created A : Inside init of A A : Creating object of B ThreadSafeSingletonClass : Inside __call__ of ThreadSafeSingleton ThreadSafeSingletonClass : Called By<class 'B.B'> ThreadSafeSingletonClass : Trying to get lock
它被卡在那里。我无法理解,因为A是一个单独的单例,而B是一个单独的单例,为什么创建B对象依赖于其他人来释放锁?如果这不是正确的方法,那么如何实现Singleton类成为可重用模块的目标。
目标
目的是将单例元类作为模块,这样,任何想要实现单例的类都必须将其作为其模块的一部分导入,并将其用作元类,而不是每次在每个模块文件中都定义该类。背景
我正在学习设计模式,并且一直在研究Python中的Singleton模式。目前,我正在尝试在模块中定义一个线程安全单例元类,而该模块又应该导入被其他类作为自己的元类。问题,我一直在尝试创建一个线程安全的SingletonClass作为模块,可以通过将其作为其他python脚本中的模块导入来重用。更像import并将其用作...
您在ThreadSafeSingleton.__call__
内部,直到A()
返回对象。因此,如果您将此函数嵌套在另一个调用中,则必须为每个类使用单独的锁。