
class AppConfig: def __new__(cls, *args, **kwargs): if not hasattr(cls,'_instance'): cls._instance=super(AppConfig,cls).__new__(cls) return cls._instance app = AppConfig() app.name = '单例模式' del app app2 = AppConfig() print("app2 name=",app2.name) from weakref import WeakValueDictionary class AppConfig(object): _instance = WeakValueDictionary() def __new__(cls): if cls not in cls._instance: inst = super().__new__(cls) cls._instance[cls] = inst return cls._instance[cls] app = AppConfig() app.name = 2 del app app2 = AppConfig() print("app2 name=",app2.name,) 1 leavic 2022-06-23 17:43:32 +08:00 我今天才知道 python 还有 del app 这种写法 |
2 dcsuibian 2022-06-23 17:47:04 +08:00 via Android 作用域不同。 |
3 dcsuibian 2022-06-23 17:53:38 +08:00 via Android 似乎说法不太对。app 和 AppConfig 类的_instance 都引用一个东西,app 这个引用消失了,但引用的东西没消失 |
4 Hstar 2022-06-23 17:53:54 +08:00 因为 del app 并没有删除对象,只是删掉了这个对象在此的引用 |
5 cz5424 2022-06-23 17:55:14 +08:00 del app 并且 del app. _instance 试试 |
6 wuwukai007 OP @cz5424 这个代码一致性就破坏了 |
7 ChrisFreeMan 2022-06-23 18:05:46 +08:00 via iPhone 你要手动实现__del__ |
8 wuwukai007 OP @ChrisFreeMan 试过了,不行的,你试试看?__del__ 只有在程序结束后才会调用,del 不会调用的 |
9 nyxsonsleep 2022-06-23 18:13:29 +08:00 这个问题如果用过 pyqt 应该会映像深刻。。。 个人理解 del 实质上没有删除对象的存在,有时会导致 pyqt 删除 gui 时出问题。 |
10 deplivesb 2022-06-23 18:13:54 +08:00 python 里面的 del 可和 c 系列的 del 不是一个作用,del 也不会调用 __del__ |
11 fatigue 2022-06-23 18:14:24 +08:00 _instance 是挂在类下面的, 你 AppConfig()的时候把这个引用返回给你,你 del 的时候把这个引用删除,_instance 一直都在,下次 AppConfig()再返回给你 |
12 ChrisFreeMan 2022-06-23 18:27:20 +08:00 __del__试了下确实不行,这样,其实你是把单例对象赋值给了类,其实那个单例对象是个类对象 你用反射检查一下有没有单例对象再删除。 class Test: def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance'): cls._instance = super().__new__(cls) return cls._instance app = Test() app.name = 'some thing1' if hasattr(Test, '_instance'): del Test._instance app2 = Test() print(app2.name) |
13 ysy950803 2022-06-23 18:41:41 +08:00 依附于类,而不是对象。 |
14 jinliming2 2022-06-23 21:49:39 +08:00 单例模式允许删除重新创建吗? 我理解的单例模式,一个类只能有一个对象,其他人来访问的时候可以直接拿到这个对象。 但没听说过还能有人可以删除掉这个单例对象,然后让重新创建一个……? |
15 4BVL25L90W260T9U 2022-06-23 22:15:25 +08:00 除了面试,没用过单例模式…… |
16 ruanimal 2022-06-23 22:55:37 +08:00 lz 没理解 del 和 Python 对象,4 楼的是正解 |
17 zxCoder 2022-06-23 23:05:41 +08:00 @jinliming2 我也没听说过,之前学过的都是你这种说法 |
18 xuboying 2022-06-23 23:49:28 +08:00 好像 del 的行为只是一个请求,实际删除 instance 的时机是不可控的。即使用了 weakref ,在官方例子中还调用了 gc 回收,才能强制请求删除。 还有一个问题是不确定这个行为在非 cPython 的环境下是不是一致的。 |
19 lanlanye 2022-06-24 08:18:58 +08:00 via iPhone Python 最流行的单例模式难道不是直接初始化然后 import ? |
20 InvincibleDream 2022-06-24 09:14:52 +08:00 |
21 45HXlKzal6W56zUJ 2022-06-24 16:13:33 +08:00 你主动删除的,不关单例的事吧.. |
22 catsoul 2022-06-24 16:54:56 +08:00 单例模式正常来说是不让你销毁这个唯一实例的... |
23 Macv1994 2022-06-25 14:03:17 +08:00 单例模式不就是为了只有一个实例么? |
24 qbqbqbqb 2022-07-04 15:46:59 +08:00 del 不是删除对象,是删除变量。可以近似理解成,语义上相当于一个更强的"=null"(和 Java ,C#等语言相比). 就和你在 Java 里写如下代码一样: AppConfig app = AppConfig.getInstance(); app = null; 这样做显然不会销毁单例。和 Python 里的这种情况是一回事。 |
25 yagamil 2022-07-09 17:33:00 +08:00 其实楼主给出的解决方案也挺好的呀。 |
26 Kobayashi 2022-07-09 20:07:31 +08:00 你咋不说它实现的不是线程安全的,多线程情况下可能同时创建多个实例呢?:P |