Различия между версиями 8 и 9
Версия 8 от 2020-11-25 22:02:53
Размер: 3474
Редактор: FrBrGeorge
Комментарий:
Версия 9 от 2020-11-26 19:48:19
Размер: 3508
Редактор: FrBrGeorge
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 37: Строка 37:
 * получилось примерно так (как обычно, это не догма, и вообще неприлично длинные строки):
 {{attachment:fieldcounter.png}}
 * Тизер, он же спойлер (строки в нём длинные, можно было сделать и поизящнее, но зато он совсем короткий):
 /* {{attachment:fieldcounter.png}} */

Написать функцию,Stat() которая умеет выполнять две роли:

  • С одним параметром Stat(класс) — работает как декоратор класса

    • Добавляет в объекты класса сбор статистики по всем полям данных
      • упомянутым в самом классе (т. е. встречающимся в vars(класс))

      • имя которых не начинается с "_"

    • По всем остальным атрибутам (методам, спецметодам и т. п., а так же атрибутам, динамически добавленным в __init__() и других методах) статистика не ведётся

  • С двумя параметрами Stat(объект, "поле") — выводит статистику использования поля поле: два целых числа (количество чтений, количество записей)

    • объект — экземпляр класса, декорированного с помощью Stat

    • поле — поле этого класса

    • Если статистика по данному полю не ведётся, или поля не существует, обя значения равны 0
  • Экземпляр класса инициализируется с помощью __init__(), т. е. класс не является потомком встроенного класса, не переопределяет __new__(), __getattribute__() и т. п., изначально не содержит слотов/дескрипторов.

   1 @Stat
   2 class C:
   3     A, B = 3, 4
   4     def __init__(self, a=None):
   5         if a:
   6             self.A = a
   7 
   8 c, d = C(), C(123)
   9 print(Stat(c, "A"), Stat(d, "A"))
  10 d.A = c.A * 2 + c.B
  11 c.B = d.A - 1 - len([d.B, d.B, d.B])
  12 print(Stat(c, "A"), Stat(c, "B"))
  13 print(Stat(d, "A"), Stat(d, "B"))
  14 print(Stat(c, "Foo"))
  • Подсказка. Я делал так:
    • Изготавливал унаследованный класс (возможно, это не обязательно, и можно модифицировать прямо исходный)
    • Прямо в классе составлял словарь полей, за которыми надо следить (да-да, внутри определения класса вы можете писать любой код, не только A = 1 ☺) и их значений

    • Прямо в классе подменял все эти поля property-ями, примерно так: setattr(cls, attr, property(getter, setter))

      • При этом getter и setter для каждого поля изготавливается всякий раз заново
    • В __init__()-е объекта делал копию хранилища имён/значений и заводил пустой счётчик (к ним будут ходить все getterы и setterы)

  • Тизер, он же спойлер (строки в нём длинные, можно было сделать и поизящнее, но зато он совсем короткий):

(0, 0) (0, 1)
(1, 0) (1, 1)
(1, 2) (3, 0)
(0, 0)


CategoryHomework

LecturesCMC/PythonIntro2020/Homework_FieldCounter (последним исправлял пользователь FrBrGeorge 2020-11-26 19:48:19)