代码的问题是,您正在设置Pro实例的属性,该属性将由所有实例共享
Something
。若要解决此问题,应在
某物
,一种方法是使用元类:
class Meta(type):
def __new__(cls, name, bases, dct):
for k, v in dct.items():
if isinstance(v, Pro):
# add an _ in front of the name
v.name = '_' + k
return super(Meta, cls).__new__(cls, name, bases, dct)
class Pro(object):
def __get__(self, ins, typ):
return getattr(ins, self.name)
def __set__(self, ins, val):
setattr(ins, self.name, val)
class Something(object):
"""My simple class"""
__metaclass__ = Meta
pro = Pro()
a = Something()
a.pro = 1
b = Something()
b.pro = 2
演示:
>>> a.pro, b.pro
(1, 2)
>>> a.__dict__
{'_pro': 1}
>>> b.__dict__
{'_pro': 2}
>>> a.pro = 100
>>> a.__dict__
{'_pro': 100}
因此,无法在Something中创建隐藏属性
实例,对吗?
不,有。你可以在
Pro
的实例,该实例存储与
某物
。例如,如果
某物
的实例是可散列的,然后可以使用
weakref.WeakKeyDictionary
这个
WeakKeyDictionary
将确保
某物
的实例没有剩余的引用,那么它将立即被垃圾收集,这在正常情况下是不可能的
dict
:
from weakref import WeakKeyDictionary
class Pro(object):
def __init__(self):
self.instances = WeakKeyDictionary()
def __get__(self, ins, typ):
return self.instances[ins]
def __set__(self, ins, val):
self.instances[ins] = val
p = Pro()
class Something(object):
"""My simple class"""
pro = p
a = Something()
a.pro = 1
b = Something()
b.pro = 2
print a.pro, b.pro
print p.instances.items()
del a
print p.instances.items()
输出:
1 2
[(<__main__.Something object at 0x7fb80d0d5310>, 1), (<__main__.Something object at 0x7fb80d0d5350>, 2)]
[(<__main__.Something object at 0x7fb80d0d5350>, 2)]