Дескриптор данных
Необходимо описать класс-дескриптор, который хранит в себе произвольные значения. Этот класс должен содержать метод null(), который будет "обнулять" все ранее сохраненные значения. Загвоздка в том, как мне получить ссылки на все объекты-владельцы этого дескриптора.
class Nuller(object):
def __set__(self, instance, value):
self.value = value
def __get__(self, instance, owner):
return self.value
def __delete__(self, value):
del self.value
def null():
print('reset')
class Team:
score = Nuller()
team1 = Team()
team2 = Team()
team1.score = 5 #5
team2.score = 28 #28
Nuller.null()
print(team1, team2) #0 0
Ответы (2 шт):
Добавляем в класс Nuller множество, в котором будем хранить объекты и названия полей, которые нужно обнулить. При записи чего-то в поле (вызов метода __set__) добавляем объект и имя поля в это множество. При вызове метода null проходим это множество и обнуляем значения записанных полей в записанных объектах.
Также обратите внимание, что запись/получение данных идет через
instance (в данном случае это будут объекта класса Team), а не через self (объект класса Nuller), т.к. объект Nuller создается один раз при создании поля класса, в итоге будет один объект Nuller на все объекты Team (в вашем примере из вопроса после team1.score = 5 все объекты класса Team будут в score показывать 5, а после team2.score = 28 - будут показывать 28).
class Nuller(object):
instances_and_attributes = set()
def __set_name__(self, owner, name):
# Значения фактически будут записываться в поле с добавлением подчеркивания
self.private_name = '_' + name
def __set__(self, instance, value):
# Добавляем объект и приватное имя поля в список обнуления
# (если обнулять по публичному имени поля, то вызов метода __set__ зациклится)
self.instances_and_attributes.add((instance, self.private_name))
setattr(instance, self.private_name, value)
def __get__(self, instance, owner):
return getattr(instance, self.private_name)
def __delete__(self, instance):
delattr(instance, self.private_name)
def null():
print('reset')
for instance, name in Nuller.instances_and_attributes:
setattr(instance, name, 0)
class Team:
score = Nuller()
team1 = Team()
team2 = Team()
team1.score = 5
team2.score = 28
print(team1.score, team2.score) # 5 28
Nuller.null()
print(team1.score, team2.score) # 0 0
Если вопрос с доступом к атрибутам класса, то можете использовать магический метод __dict__:
class E():
def __init__(self):
self.rod = 10
class Er(E):
def __init__(self, val1, val2):
super(Er, self).__init__()
self.val1 = val1
self.val2 = val2
def x2_val1(self):
self.val1 = self.val1 * 2
def null(self):
for key in self.__dict__:
self.__dict__[key] = 0
obj = Er(4, 5)
obj.null()
print(obj.val1) # выведет 0
print(obj.rod) # выведет 0