Проблема с вашим кодом заключается в том, что вы устанавливаете атрибут экземпляра Pro, который будет использоваться всеми экземплярами Something
. Чтобы исправить это, вы должны установить атрибут для отдельного экземпляра 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
, в котором хранятся все значения, относящиеся к каждому экземпляру Something
. Например, если экземпляры Something
можно хешировать, вы можете сделать что-то подобное, используя weakref.WeakKeyDictionary
< /а>. WeakKeyDictionary
позаботится о том, чтобы после того, как у экземпляра Something
не осталось ссылок, он был немедленно собран мусором, что невозможно с обычным 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)]
person
Ashwini Chaudhary
schedule
29.01.2015