проблема
Я работаю над проектом Python, основным классом которого является « Объект Бога ». Существует так много чертовых атрибутов и методов!
Я хочу изменить класс.
Уже…
Для первого шага я хочу сделать что-то относительно простое; но когда я попробовал самый простой подход, он сломал некоторые тесты и существующие примеры.
По сути, у класса есть довольно длинный список атрибутов, но я могу четко просмотреть их и подумать: «Эти 5 атрибутов связаны ... Эти 8 также связаны ... а затем есть остальные».
GetAttr
Я просто хотел сгруппировать связанные атрибуты в вспомогательный класс, похожий на dict. У меня было ощущение, __getattr__
что это идеально подходит для работы. Поэтому я переместил атрибуты в отдельный класс и, конечно же, __getattr__
отлично справился со своей магией ...
Во первых .
Но затем я попытался запустить один из примеров. Подкласс примера пытается установить один из этих атрибутов напрямую (на уровне класса ). Но так как атрибут больше не был «физически расположен» в родительском классе, я получил сообщение о том, что атрибут не существует.
@имущество
Я тогда прочитал о @property
декораторе. Но потом я также прочитал, что это создает проблемы для подклассов, которые хотят делать, self.x = blah
когда x
это свойство родительского класса.
Желаемый
- Пусть весь клиентский код продолжает работать
self.whatever
, даже еслиwhatever
свойство родителя не «физически расположено» в самом классе (или экземпляре). - Сгруппируйте связанные атрибуты в похожие на dict контейнеры.
- Уменьшите чрезмерную шумность кода в основном классе.
Например, я не просто хочу изменить это:
larry = 2
curly = 'abcd'
moe = self.doh()
В это:
larry = something_else('larry')
curly = something_else('curly')
moe = yet_another_thing.moe()
... потому что это все еще шумно. Хотя это успешно превращает простой атрибут во что-то, что может управлять данными, оригинал имел 3 переменные, а измененная версия все еще имеет 3 переменные.
Тем не менее, я был бы в порядке с чем-то вроде этого:
stooges = Stooges()
И если поиск self.larry
не удастся, что-то проверит stooges
и посмотрит, есть ли larry
там. (Но это также должно работать, если подкласс пытается сделать это larry = 'blah'
на уровне класса.)
Резюме
- Хотите заменить связанные группы атрибутов в родительском классе одним атрибутом, который хранит все данные в другом месте
- Хотите работать с существующим клиентским кодом, который использует (например)
larry = 'blah'
на уровне класса - Хотите продолжать разрешать подклассам расширять, переопределять и изменять эти измененные атрибуты, не зная, что что-то изменилось
Это возможно? Или я лаю не на том дереве?