Re: [問題] 如何找到class的instance??

看板Python作者 (偶爾想擺爛一下)時間15年前 (2009/11/27 18:10), 編輯推噓2(200)
留言2則, 2人參與, 最新討論串8/10 (看更多)
※ 引述《KSJ (阿真)》之銘言: : : all_a[0] 是b這個instance : : all_a[1] 是c這個instance : : 好讓我能找到 b底下的一些參數 : : 其實我也不懂為什麼globals() 裡面會有同名的module跟instance : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ : 這句話就好像 在dictionary裡 有二個一樣的key : 但裡面存著不同的東西 : 不可思議 但在qgis的python console下真的存在@_@a : 我目前的解決辨法是 類似於 前幾篇的文章中 : "把instance放入instance的property中" : 不過因為instance抓不到 所以也沒辨法抓到instance中的property : 所以我就把 "instance放入比它自己還上一層的某個class的property中" : (我想我說的class應該也是某個instance吧) : 再去看它的 property 就是 我想要的instance了 : 不過這的確會碰到 所謂的 每個instance都會不能清除的問題 如果你的需求是在任意時刻訪問一 class/type 的所有 live object,那麼 globals() 回報的 mapping 裡有同名的現象(雖然我不認為會有)並無關緊要, live object 表示有一個以上的 strong reference 指向它,這些 strong reference 在哪並不重要。 要達到你的需求,之前版友 Falldog 提供的作法加上 weakref module 的協助 就可以實做出一個可接受的方案: from weakref import WeakValueDictionary class foo(object): __live_objects = WeakValueDictionary() def __new__(cls, *args): obj = super(foo, cls).__new__(cls, *args) cls.__live_objects[id(obj)] = obj return obj def __init__(self, data=None): self.data = data @staticmethod def visit_live_objects(visitor): for x in foo.__live_objects.itervalues(): visitor(x) # demo code: def dump(x): print x.data, A=map(foo, ('Item %d' % x for x in xrange(10))) foo.visit_live_objects(dump) # output: # Item 7 Item 8 Item 0 Item 1 Item 2 Item 3 Item 4 Item 5 Item 9 Item 6 del A[5:] foo.visit_live_objects(dump) # output: # Item 3 Item 0 Item 2 Item 4 Item 1 a = foo('PTT') foo.visit_live_objects(dump) # output: # Item 3 PTT Item 0 Item 2 Item 4 Item 1 a='ptt' foo.visit_live_objects(dump) # output: # Item 3 Item 0 Item 2 Item 4 Item 1 如果考慮到可能數個 class/type 都有此種需求,而且這個需求某種程度上也 算是一種通用的 feature,可以考慮寫成 meta class 來為多個 class 提供 cache live object 的支援。 大致上如下: class metaLiveObjectCache(type): def __init__(cls, name, bases, attrs): super(metaLiveObjectCache, cls).__init__(cls, name, bases, attrs) setattr(cls, '_%s__live_objects' % cls.__name__, WeakValueDictionary()) # hook __new__ old_new = cls.__new__ def proxy_new(klass, *args): obj = old_new(klass, *args) getattr(cls, '_%s__live_objects' % cls.__name__)[id(obj)] = obj return obj proxy_new.__name__ = old_new.__name__ proxy_new.__doc__ = old_new.__doc__ cls.__new__ = staticmethod(proxy_new) # install static method: visit_live_objects def visit_live_objects(visitor): for x in getattr(cls, '_%s__live_objects' % cls.__name__).itervalues(): visitor(x) cls.visit_live_objects = staticmethod(visit_live_objects) 前一例中的 foo class 可以簡化如下: class bar(object): __metaclass__ = metaLiveObjectCache def __init__(self, data=None): self.data = data -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.173.132.87

11/27 18:55, , 1F
好文!
11/27 18:55, 1F
※ 編輯: sbrhsieh 來自: 218.173.132.87 (11/27 19:25)

11/29 22:18, , 2F
11/29 22:18, 2F
文章代碼(AID): #1B3wMmQl (Python)
討論串 (同標題文章)
文章代碼(AID): #1B3wMmQl (Python)