dws*_*ein 19 python dictionary class self instances
在程序结束时,我希望将类的所有实例中的特定变量加载到字典中.
例如:
class Foo():
__init__(self):
x = {}
foo1 = Foo()
foo2 = Foo()
foo...etc.
Run Code Online (Sandbox Code Playgroud)
假设实例的数量会有所不同,我希望每个Foo()实例的x dict都加载到一个新的dict中.我该怎么办?
我在SO中看到的例子假设一个已经有实例列表.
Joe*_*ett 33
跟踪实例的一种方法是使用类变量:
class A(object):
instances = []
def __init__(self, foo):
self.foo = foo
A.instances.append(self)
Run Code Online (Sandbox Code Playgroud)
在程序结束时,您可以像这样创建你的dict:
foo_vars = {id(instance): instance.foo for instance in A.instances}
Run Code Online (Sandbox Code Playgroud)
只有一个清单:
>>> a = A(1)
>>> b = A(2)
>>> A.instances
[<__main__.A object at 0x1004d44d0>, <__main__.A object at 0x1004d4510>]
>>> id(A.instances)
4299683456
>>> id(a.instances)
4299683456
>>> id(b.instances)
4299683456
Run Code Online (Sandbox Code Playgroud)
Blc*_*ght 25
@ JoelCornett的答案完美地涵盖了基础知识.这是一个稍微复杂的版本,可能有助于解决一些微妙的问题.
如果您希望能够访问给定类的所有"实时"实例,请将以下子类化(或在您自己的基类中包含等效代码):
from weakref import WeakSet
class base(object):
def __new__(cls, *args, **kwargs):
instance = object.__new__(cls, *args, **kwargs)
if "instances" not in cls.__dict__:
cls.instances = WeakSet()
cls.instances.add(instance)
return instance
Run Code Online (Sandbox Code Playgroud)
这解决了@JoelCornett提出的更简单实现的两个可能问题:
每个子类base将分别跟踪它自己的实例.您不会在父类的实例列表中获取子类实例,并且一个子类永远不会在兄弟子类的实例上发现.根据您的使用情况,这可能是不合需要的,但将这些集合重新组合起来可能比将它们拆分开来更容易.
该instances集使用对类的实例的弱引用,因此如果您del或在代码中的其他位置重新分配对实例的所有其他引用,则簿记代码将不会阻止它被垃圾回收.同样,对于某些用例来说,这可能并不理想,但如果您真的希望每个实例都能永久使用,那么使用常规集(或列表)而不是弱集很容易.
一些方便的测试输出(instances总是传递集合list只是因为它们不能很好地打印出来):
>>> b = base()
>>> list(base.instances)
[<__main__.base object at 0x00000000026067F0>]
>>> class foo(base):
... pass
...
>>> f = foo()
>>> list(foo.instances)
[<__main__.foo object at 0x0000000002606898>]
>>> list(base.instances)
[<__main__.base object at 0x00000000026067F0>]
>>> del f
>>> list(foo.instances)
[]
Run Code Online (Sandbox Code Playgroud)
小智 8
您可能希望对实例使用弱引用.否则,该类可能最终会跟踪要删除的实例.weakref.WeakSet将自动从其集合中删除任何死实例.
跟踪实例的一种方法是使用类变量:
import weakref
class A(object):
instances = weakref.WeakSet()
def __init__(self, foo):
self.foo = foo
A.instances.add(self)
@classmethod
def get_instances(cls):
return list(A.instances) #Returns list of all current instances
Run Code Online (Sandbox Code Playgroud)
在程序结束时,您可以像这样创建你的dict:
foo_vars = {ID(实例):instance.foo例如在A.instances}只有一个清单:
>>> a = A(1)
>>> b = A(2)
>>> A.get_instances()
[<inst.A object at 0x100587290>, <inst.A object at 0x100587250>]
>>> id(A.instances)
4299861712
>>> id(a.instances)
4299861712
>>> id(b.instances)
4299861712
>>> a = A(3) #original a will be dereferenced and replaced with new instance
>>> A.get_instances()
[<inst.A object at 0x100587290>, <inst.A object at 0x1005872d0>]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20825 次 |
| 最近记录: |