Re: [問題] 如何找到class的instance??
※ 引述《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
討論串 (同標題文章)
Python 近期熱門文章
PTT數位生活區 即時熱門文章