С помощью дескриптора вы можете определить желаемое поведение атрибутов вашего объекта. Читая между строк, звучит так, будто вы хотите, чтобы ваши атрибуты демонстрировали поведение value = value % maximum
.
from weakref import WeakKeyDictionary
class MaxValue:
'''A descriptor whose value will be: value modulo maximum.'''
def __init__(self, maximum, default=0):
self.maximum = maximum
self.default = default
self.data = WeakKeyDictionary()
def __get__(self, instance, owner):
return self.data.get(instance, self.default)
def __set__(self, instance, value):
self.data[instance] = value % self.maximum
Дескрипторы должны быть атрибутами класса. Для вашего примера класса:
import random
width = 100
height = 100
class Item:
## global width, height
x = MaxValue(width)
y = MaxValue(height)
def __init__(self):
self.x = random.randint(0, width)
self.y = random.randint(0, height)
def __str__(self):
return f'({self.x:>3},{self.y:>3})'
Пример:
items = [Item() for _ in range(5)]
print(','.join(f'{item}' for item in items))
for n in range(15):
for item in items:
item.x += 10
item.y += 20
print(','.join(f'{item}' for item in items))
>>>
( 74, 6),( 49, 19),( 56, 10),( 72, 16),( 83, 16)
( 84, 26),( 59, 39),( 66, 30),( 82, 36),( 93, 36)
( 94, 46),( 69, 59),( 76, 50),( 92, 56),( 3, 56)
( 4, 66),( 79, 79),( 86, 70),( 2, 76),( 13, 76)
( 14, 86),( 89, 99),( 96, 90),( 12, 96),( 23, 96)
( 24, 6),( 99, 19),( 6, 10),( 22, 16),( 33, 16)
( 34, 26),( 9, 39),( 16, 30),( 32, 36),( 43, 36)
( 44, 46),( 19, 59),( 26, 50),( 42, 56),( 53, 56)
( 54, 66),( 29, 79),( 36, 70),( 52, 76),( 63, 76)
( 64, 86),( 39, 99),( 46, 90),( 62, 96),( 73, 96)
( 74, 6),( 49, 19),( 56, 10),( 72, 16),( 83, 16)
( 84, 26),( 59, 39),( 66, 30),( 82, 36),( 93, 36)
( 94, 46),( 69, 59),( 76, 50),( 92, 56),( 3, 56)
( 4, 66),( 79, 79),( 86, 70),( 2, 76),( 13, 76)
( 14, 86),( 89, 99),( 96, 90),( 12, 96),( 23, 96)
( 24, 6),( 99, 19),( 6, 10),( 22, 16),( 33, 16)
>>>
Не моя идея - поднял это на Дескрипторы Python Демистифицированы
Каждый экземпляр MaxValue
должен отслеживать (или знать ), значение для каждого экземпляра Item
- Item.x
должно знать значение x
для Item
экземпляров a
, b
, c
, .... Для этого удобен словарь, и используется WeakKeyDictionary, так что если словарь является единственной ссылкой на экземпляр Item
, то этот экземпляр может быть подвергнут сборке мусора.
Это решение избавляет от необходимости писать getter / setter для каждого атрибута, который разделяет поведение.