Fra*_*y_V 5 python metaclass python-3.x
我需要跟踪某些类的实例(并对这些类执行其他操作)。我希望不必在相关类中声明任何额外的代码,因此理想情况下所有内容都应该在元类中处理。
我不知道如何向这些类的每个新实例添加弱引用。例如:
class Parallelizable(type):
def __new__(cls, name, bases, attr):
meta = super().__new__(cls, name, bases, attr)
# storing the instances in this WeakSet
meta._instances = weakref.WeakSet()
return meta
@property
def instances(cls):
return [x for x in cls._instances]
class Foo(metaclass=Parallelizable)
def __init__(self, name):
super().__init__()
self.name = name
# I would like to avoid having to do that - instead have the metaclass manage it somehow
self._instances.add(self)
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?我似乎无法在元类方面找到一个钩子来进入__init__Foo 的......
当元类的“附属”类的每个新实例为 时调用的元类上的方法__call__。如果您将记录实例的代码放在那里,这就是您需要做的全部工作:
from weakref import WeakSet
# A convenient class-level descriptor to retrieve the instances:
class Instances:
def __get__(self, instance, cls):
return [x for x in cls._instances]
class Parallelizable(type):
def __init__(cls, name, bases, attrs, **kw):
super().__init__(name, bases, attrs, **kw)
cls._instances = WeakSet()
cls.instances = Instances()
def __call__(cls, *args, **kw):
instance = super().__call__(*args, **kw)
cls._instances.add(instance)
return instance
Run Code Online (Sandbox Code Playgroud)
相同的代码在没有描述符的情况下也可以工作——这只是一个拥有报告实例的类属性的好方法。但如果 WeakSet 就足够了,那么这段代码就足够了:
from weakref import WeakSet
class Parallelizable(type):
def __init__(cls, name, bases, attrs, **kw):
super().__init__(name, bases, attrs, **kw)
cls.instances = WeakSet()
def __call__(cls, *args, **kw):
instance = super().__call__(*args, **kw)
cls.instances.add(instance)
return instance
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
544 次 |
| 最近记录: |