Проблема
Я працюю над проектом Python, головним класом якого є “ God Object ”. Існує так багато атрибутів і методів!
Я хочу переробити клас.
Так далеко…
Для першого кроку я хочу зробити щось відносно просте; але коли я спробував найпростіший підхід, він зламав деякі тести та існуючі приклади.
В основному, у класу є список атрибутів, що перебувають у лунго, але я чітко переглядаю їх і думаю: «Ці 5 атрибутів пов’язані між собою… Ці 8 також пов’язані між собою… і тоді є решта».
гетатр
Я в основному просто хотів згрупувати пов'язані атрибути в клас, що нагадує дікт. У мене було відчуття, що __getattr__
це буде ідеально для роботи. Тож я перенесла атрибути в окремий клас і, безумовно, добре __getattr__
працювала над його магією ...
На першому .
Але потім я спробував запустити один із прикладів. Приклад підкласу намагається встановити один з цих атрибутів безпосередньо (на рівні класу ). Але оскільки атрибут більше не був "фізично розташований" у батьківському класі, я отримав помилку, сказавши, що атрибут не існує.
@ властивість
Потім я читав про @property
декоратора. Але потім я також прочитав, що це створює проблеми для підкласів, які хочуть робити, self.x = blah
коли x
це властивість батьківського класу.
Бажаний
- Нехай весь код клієнта продовжує працювати
self.whatever
, навіть якщоwhatever
властивість батьків не знаходиться "фізично" в самому класі (або екземплярі). - Атрибути, пов'язані з групою, у контейнери, що нагадують дикти.
- Зменшіть надзвичайну галасливість коду в основному класі.
Наприклад, я не хочу просто змінити це:
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'
на рівні класу - Хочете надалі дозволяти підкласам розширювати, змінювати та змінювати ці відновлені атрибути, не знаючи, що щось змінилося
Чи можливо це? Або я гавкаю неправильне дерево?