作者sbrhsieh (偶尔想摆烂一下)
看板Python
标题Re: [问题] 如何找到class的instance??
时间Fri Nov 27 18:10:53 2009
※ 引述《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
1F:推 timTan:好文! 11/27 18:55
※ 编辑: sbrhsieh 来自: 218.173.132.87 (11/27 19:25)
2F:推 Falldog:酷 11/29 22:18