skip to navigation
skip to content

feed icon RSS хранилка

Пета задача

Публикувано на 12.04.2007 15:24 от николай
Последна промяна на 18.04.2007 23:43
Тази публикация е от предишно издание на курса, моля не разчитайте на актуалността на информацията.

Брой точки, които дава задачата: 5.

Краен срок: 23-и април, 19:00 часа.

Формуляр за изпращане.

Основната идея на задачата е да се напише клас (даже 2), който търси атрибути в йерархия от класове.

Какво представлява търсенето на атрибути?

Ако имаме клас и име на атрибут, то търсенето на атрибут представлява проверка в кой клас от йерархията (родители на дадения) първо се среща дадения атрибут. Обхождането може да стане по два начина—в ширина и в дълбочина.

Пример

Примерна йерархия за 5-а задача

Нека разгледаме горния пример, в който А наследява B и C, а B наследява D. Ако се опитаме в A да търсим атрибута x с търсене в дълбочина ще го намерим в класа D, а ако го търсим с търсене в ширина ще го намерим в класа C.

Код, код, код

Сега да пристъпим към конкретното описание на модула, който трябва да се напише.

В модула трябва да присъстват 2 атрибута: BFS и DFS, които ще отговарят на двата метода на търсене. Стойностите им нямат значение, стига да са различни и да не се променят.

Основната логика ще стои в класа Resolver:

  • __init__(self, cls, method=BFS) — cls е класът, в който ще търсим атрибути, а method е методът, по който ще ги търсим (виж атрибутите BFS и DFS по-горе)
  • класът трябва да поддържа оператора . (точка, __getattribute__) като обръщение от типа obj.attr, където obj е от тип Resolver, трябва да върне:
    • атрибутът на obj с име attr, ако attr започва с долна черта (_) Няма значение какво е поведението на Resolver при атрибути започващи с долна черта. Подобни тестове няма да има!
    • None, ако атрибутът не е намерен в cls и неговите родителски класове по зададения метод
    • обект а атрибути cls и value, в които стоят съответно класа, където е намерен атрибута, и стойността на атрибута в този клас

Също така трябва да се напише помощен клас ValueResolver, чийто конструктор има същата сигнатура, но оператора точка работи по малко по-различен начин. Ако атрибутът е намерен се връща стойността му, а ако не е намерен се хвърля AttributeError. ValueResolver трябва да наследява Resolver.

Забележки

  • Не може да сте сигурни от кой тип (стар, нов) са класовете, които ви се дават.
  • Ако класовете са от нов тип, то те няма да ползват __slots__.
  • За да проверявате дали клас има определен атрибут ползвайте неговия __dict__, защото (has|get)attr търсят в цялата йерархия.
  • Родителите на даден клас трябва да се обхождат в реда на появяването им в списъка с родители, който съвпада с реда на елементите в __bases__.

Примерни тестове

Подготвили сме ви скриптче, в което има няколко примерни теста. За да го изпълните е достатъчно да имате модул с име p5 съдържаш, това което се искаше от вас. Най-лесно е да си кръстите програмата p5.py и да я сложите в същата директория, където и p5-sample.py.

Връзка: p5-sample.py