Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 1606.pdf
Скачиваний:
18
Добавлен:
30.04.2022
Размер:
1.48 Mб
Скачать

Значение поля : Красный

Принадлежность : Класс MyClass Спрашивает Красный : Класс MyClass Спрашивает Зеленый : Здесь был Зеленый

Спрашивает Красный : Здесь могла быть Ваша реклама! Спрашивает Зеленый : здесь был Зеленый

Спрашивает Зеленый : Здесь могла быть Ваша реклама!

Ранее мы с помощью инструкции green.name считывали значение поля name, поэтому имеем некоторые основания рассчитывать на успех. Однако при выполнении команды print("Спрашивает Красный:", red.name) получаем в окне вывода сообщение Спрашивает Красный : Класс MyClass. То есть значение поля name, полученное по ссылке через экземпляр red не изменилось. Хотя при выполнении команды print ("Спрашивает Зеленый:" , green.name ) в окне вывода получаем вполне ожидаемое сообщение Спрашивает Зеленый: Здесь был Зеленый. Поворот событий достаточно неожиданный: пока мы через инструкцию green.name значение полю name не присваивали, значения выражений green.name и red.name совпадали, но после присваивания значения полю эти инструкции возвращают разные значения. Объяснение такое. При выполнении команды green.nаmе= "Здесь был Зеленый" на самом деле значение полю name класса MyClass не присваивается. Вместо этого создается поле с названием nare у экземпляра green, и этому полю присваивается значение "Здесь был Зеленый". И после этого каждый раз, когда мы будем использовать инструкцию green.name, она будет означать не поле name класса MyClass, а поле nare экземпляра green. Другими словами, поле name экземпляра green "перекрывает" поле nare класса MyClass. Но это только для экземпляра green. У экземпляра red поля name нет, поэтому инструкция red.name при считывании значения означает поле name класса MyClass.

При выполнении команды MyClass.nаmе= " Здесь могла быть Ваша реклама!" изменяется значение поля name класса MyClass. Поэтому когда в команде print ("Спрашивает Красный: ", red.name) используется ссылка red.name, то результатом этой инструкции будет новое значение поля name класса MyClass. А значение инструкции green.name в команде print ("Спрашивает Зеленый: " , green . name ) - это значение " Здесь был Зеленый " поля name экземпляра green.

На следующем этапе командой del(green.name) у экземпляра green удаляется поле name. После этого у экземпляра green поля name уже нет, и значением инструкции green.name в команде print("Спрашивает Зеленый : " , green.name ) является значение поля name класса MyClass.

5.3. Добавление и удаление полей и методов

После наших смелых экспериментов с полями объекта класса и экземпляров класса не сложно догадать, что поля можно добавлять и удалять,

52

причем это справедливо как для объекта класса, так и для экземпляров класса. Здесь мы обсудим и проанализируем две позиции:

Поля экземпляра класса можно добавлять и удалять после создания экземпляра класса.

Поля объекта класса можно добавлять и удалять после создания объекта класса.

С прикладной точки зрения ситуация в общем и целом несложная: для добавления поля экземпляра класса этому полю присваивается значение (разумеется, через ссылку на экземпляр класса). Примерно то же самое происходит при добавлении поля объекту класса: такому полю присваивается значение, и этого достаточно, чтобы у объекта класса появилось новое поле. Чтобы удалить поле у объекта класса, после оператора del указываем ссылку на поле объекта класса (в "точечном" формате: класс и, через точку, имя поля). Аналогичным образом удаляется и Поле экземпляра класса, только теперь после оператора del указывается ссылка на поле экземпляра класса (экземпляр класса, точки и имя поля).

Небольшой пример манипулирования с полями объекта класса и полями экземпляров класса приведен в листинге:

#Создаем класс class MyClass:

pass

#Создаем экземпляр А

A=MyClass()

#Создаем экземпляр В

B=MyClass()

#Экземпляру А добавляем

#поле first

А.first =" Экземпляр А "

#Экземпляру В добавляем

#поле seccond

В.second = " Экземпляр В "

#Классу MyClass добавляем

#поле total

MyClass.total= "Kлacc MyClass"

#Проверяем доступ к полям total и

#first через ссылку на экземпляр А print(А.total , " " , A.first )

#Проверяем доступ к полю second

#через ссылку на экземпляр А

try :

# Если Поле second есть print ( А.second )

# Ecли такого поля нет except AttributeError:

print ( "Taкoгo поля у экземпляра А нет ! " )

# Проверяем доступ к полям total и

53

# second через ссылку на экземпляр В print ( B.total, " " , B.second)

#Проверяем доступ к полю first

#через ссылку н а экземпляр В try:

#Если поле first есть

print(В.first )

#Если такого поля нет except AttributeError:

print ( " Taкoгo поля у экземпляра В нет ! " )

#Удаляем поле total класса MyClass del(MyClass.total)

#Проверяем доступ к полю total

#через ссылку на экземпляр А

try :

#Если поле есть print(A.total )

# Если поля нет except AttributeError:

print ( " Taкoгo поля нет ! " )

#Проверяем доступ к полю total

#через ссылку на экземпляр В try :

#Если поле есть

print (B.total)

#Если поля нет except AttributeError :

print ("Taкoгo поля нет!")

#Удаляем поле first экземпляра А del(A.first)

#Проверяем доступ к полю first

#через ссылку на экземпляр А try:

#Если поле есть

print (A.first)

# Если поля нет except AttributeError:

print ("Taкoгo поля у экземпляра А нет !")

Добавление и удаление полей

Результат выполнения программного кода такой:

Класс MyClass Экземпляр A

Такого поля у экземпляра А нет Класс MyClass Экземпляр B Такого поля у экземпляра в B нет

Такого поля нет! Такого поля нет!

54

Такого поля у экземпляра А нет!

В этом примере создается класс MyClass, не содержащий, собственно, ничего. На основе этого класса создаются два экземпляра с названиями А и B. Затем командам и А.first = "Экземпляр А", В.sесоnd= "Экземпляр В" и MyClass.total= "Kлacc MyClass" добавляются (с присваиванием значений) поля first для экземпляра А, поле second для экземпляра B и поле total для класса MyClass. В команде print (А.total , " " , А.first ) есть ссылки на поле first экземпляра класса и поле total объекта класса, причем обе ссылки выполняются через экземпляр А.

По результату выполнения команды видим, что проблем с доступом к полям не возникает. В принципе, нечто подобное мы наблюдали в предыдущих примерах, но здесь есть одна особенн6ость. Связана она с тем, что поле total появилось у класса MyClass уже после того, как были созданы экземпляры А и в. Но, тем не менее, доступ к добавленному полю total через экземпляры класса имеется. А вот добавление поля одному экземпляру класса для другого экземпляра "остается незамеченным" (что, в принципе, вполне логично).

При попытке выполнить команду print(А.second) возникает ошибка класса AttributeError: поля second у экземпляра А нет. Эту ситуацию мы обрабатываем с помощью блока try-except. Результатом является сообщение Такого поля у экземпляра А нет!, которое отображается командой print ("Такого поля у экземпляра А нет !") в ехсерt-блоке.

Аналогично обстоят дела с экземпляром B: доступ к полю total класса MyClass и полю second экземпляра через переменную В получаем без проблем, а к полю first экземпляра доступа нет, поскольку это поле добавлялось в экземпляр А, и экземпляр B к данному полю никакого отношения не имеет.

На следующем этапе командой del(MyClass.total) удаляем поле total объекта класса MyClass, после чего командой print(А.total) (в trу-блоке) пытаемся прочитать значение этого поля. Судя по тому, что в этом случае возникает ошибка класса At tributeError (неверный атрибут) и в ехсерt-блоке выполняется команда print ("Такого поля нет!"), поле total действительно удалено из объекта класса MyClass. Нет доступа к удаленному полю total и через переменную B.

Наконец, командой del(A.first) поле first экземпляра А. Как следствие, при попытке выполнить команду print (A . fir s t ) в t rу-блоке возникает ошибка. Поэтому в ехсерt-блоке выполняется команда print ("Такого поля у экземпляра А нет!").

5.4.Практические задания

1.Класс Дробное число со знаком (Fractions). Число должно быть представлено двумя полями: целая часть – длинное целое со знаком, дробная часть –беззнаковое короткое целое. Реализовать арифметические операции

55