我正在创建一个 Python 应用程序,其中包含与服务器的套接字通信。我想要一个可以在我的整个应用程序中使用的模块(其他几个模块)。目前我的模块如下所示:
class SocketCommunication:
def __init__(self):
self.socketIO = SocketIO(settings.ADDRESS, settings.PORT, Namespace)
def emit(self, message, data):
json_data = json.dumps(data.__dict__)
self.socketIO.emit(message, json_data)
class Namespace(BaseNamespace):
def on_connect(self):
print '[Connected]'
def on_disconnect(self):
print "[Disconnected]"
当我在其他模块中使用它时,我会执行以下操作:
import SocketCommunication
self.sc = SocketCommunication()
问题是,每次执行此操作时,都会创建一个新连接,该连接将在服务器上显示为新客户端,这是不可取的。 据我所知,Python 中应该避免单例,因此我很好奇解决此类问题的最佳实践是什么?
最佳答案
以下是Python中使用单例的三种方式。
使用元类
和装饰器
来达到目标。
使用
__new__
class Singleton(object): def __new__(cls, *args, **kw): if not hasattr(cls, '_instance'): orig = super(Singleton, cls) cls._instance = orig.__new__(cls, *args, **kw) return cls._instance class MyClass(Singleton): a = 1 one = MyClass() two = MyClass() two.a = 3 print one.a #3 print id(one) #29097904 print id(two) #29097904 print one == two #True print one is two #True
使用
__metaclass__
class Singleton2(type):
def __init__(cls, name, bases, dict):
super(Singleton2, cls).__init__(name, bases, dict)
cls._instance = None
def __call__(cls, *args, **kw):
if cls._instance is None:
cls._instance = super(Singleton2, cls).__call__(*args, **kw)
return cls._instance
class MyClass2(object):
__metaclass__ = Singleton2
one = MyClass2()
two = MyClass2()
two.a = 3
print one.a
#3
print id(one)
#31495472
print id(two)
#31495472
print one == two
#True
print one is two
#True
使用
装饰器
def singleton(cls, *args, **kw): instances = {} def _singleton(*args, **kw): if cls not in instances: instances[cls] = cls(*args, **kw) return instances[cls] return _singleton @singleton class MyClass3(object): a = 1 def __init__(self, x=0): self.x = x one = MyClass3() two = MyClass3() two.a = 3 print one.a #3 print id(one) #29660784 print id(two) #29660784 print one == two #True print one is two #True one.x = 1 print one.x #1 print two.x #1
我更喜欢使用装饰器
。
关于python - Python 中类的单个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42237752/