Шаг 135.
Основы языка Python. Объектно-ориентированное программирование (ООП). Определение класса и создание экземпляра класса (окончание)

    На этом шаге мы рассмотрим доступ к атрибутам и методам класса, а также особенности сосздания атрибутов.

    Для доступа к атрибутам и методам можно использовать и следующие функции:

    Продемонстрируем работу функций на следующем примере:

class MyClass:
    def  __init__(self):
        self.x = 10
    def get_x(self):
        return self.x	
c = MyClass()                  # Создаем экземпляр класса
print(getattr(c, "x"))         # Выведет: 10	 
print(getattr(c, "get_x" ) ()) # Выведет: 10
print(getattr(c, "y", 0))      # Выведет: 0, т. к. атрибут не найден
setattr(c, "y", 20)            # Создаем атрибут y	
print(getattr(c, "y", 0))      # Выведет: 20
delattr(c, "y")                # Удаляем атрибут у
print(getattr(c, "y", 0))      # Выведет: 0, т. к. атрибут не найден
print(hasattr(c, "x") )	       # Выведет: True 
print(hasattr(c, "y") )	       # Выведет: False
Архив с файлом можно взять здесь.

    Результат работы приложения:

10
10
0
20
0
True
False

    Все атрибуты класса в языке Python являются открытыми (public), т. е. доступными для непосредственного изменения как из самого класса, так и из других классов и из основного кода программы.

    Кроме того, атрибуты допускается создавать динамически после создания класса - можно создать как атрибут объекта класса, так и атрибут экземпляра класса. Рассмотрим это на следующем примере:

class MyClass:                # Определяем пустой класс
    pass
MyClass.x = 50                # Создаем атрибут объекта класса
c1, c2 = MyClass(), MyClass() # Создаем два экземпляра класса
c1.y = 10                     # Создаем атрибут экземпляра класса
c2.y = 20                     # Создаем атрибут экземпляра класса
print(c1.x, c1.y)             # Выведет: 50 10
print(c2.x, c2.y)             # Выведет: 50 20
Архив с файлом можно взять здесь.

    Результат работы приложения:

50 10
50 20

    В этом примере мы определяем пустой класс, разместив в нем оператор pass. Далее создаем атрибут объекта класса (х). Этот атрибут будет доступен всем создаваемым экземплярам класса. Затем создаем два экземпляра класса и добавляем одноименные атрибуты (y). Значения этих атрибутов будут разными в каждом экземпляре класса. Но если создать новый экземпляр (например, c3), то атрибут у в нем определен не будет. Таким образом, с помощью классов можно имитировать типы данных, поддерживаемые другими языками программирования (например, тип struct, доступный в языке С).

    Очень важно понимать разницу между атрибутами объекта класса и атрибутами экземпляра класса. Атрибут объекта класса доступен всем экземплярам класса, но после изменения атрибута значение изменится во всех экземплярах класса. Атрибут экземпляра класса может хранить уникальное значение для каждого экземпляра, и изменение его в одном экземпляре класса не затронет значения одноименного атрибута в других экземплярах того же класса. Рассмотрим это на примере, создав класс с атрибутом объекта класса (х) и атрибутом экземпляра класса (у):

class MyClass: 
    x = 10;               # Атрибут экземпляра класса
    def __init__(self):
        self.y = 20       # Атрибут экземпляра класса

c1 = MyClass()            # Создаем экземпляр класса
c2 = MyClass()            # Создаем экземпляр класса
print(c1.x, c2.x)         # Выведет: 10 10
MyClass.x = 88            # Изменяем атрибут объекта класса
print(c1.x, c2.x)         # Выведет: 88 88
print(c1.y, c2.y)         # Выведет: 20 20
c1.y = 88                 # Изменяем атрибут экземпляра класса
print(c1.y, c2.y)         # Выведет: 88 20
Архив с файлом можно взять здесь.

    Результат работы приложения:

10 10
88 88
20 20
88 20

    Сначала создается класс MyClass, а затем два экземпляра этого класса:

c1 = MyClass()            # Создаем экземпляр класса
c2 = MyClass()            # Создаем экземпляр класса

    Выведем значения атрибута x, а затем изменим значение и опять произведем вывод:

print(c1.x, c2.x)         # Выведет: 10 10
MyClass.x = 88            # Изменяем атрибут объекта класса
print(c1.x, c2.x)         # Выведет: 88 88

    Как видно из примера, изменение атрибута объекта класса затронуло значение в двух экземплярах класса сразу. Теперь произведем аналогичную операцию с атрибутом y:

print(c1.y, c2.y)         # Выведет: 20 20
c1.y = 88                 # Изменяем атрибут экземпляра класса
print(c1.y, c2.y)         # Выведет: 88 20

    В этом случае изменилось значение атрибута только в экземпляре c1.

    Следует также учитывать, что в одном классе могут одновременно существовать атрибут объекта и атрибут экземпляра с одним именем. Изменение атрибута объекта класса мы производили следующим образом:

MyClass.x = 88            # Изменяем атрибут объекта класса

    Если после этой инструкции вставить инструкцию

c1.x = 200                # Создаем атрибут экземпляра
то будет создан атрибут экземпляра класса, а не изменено значение атрибута объекта класса. Чтобы увидеть разницу, выведем значения атрибута:
print(c1.x, MyClass.x)    # Выведет: 200 88

    На следующем шаге мы рассмотрим методы __init()__ и __del()__.




Предыдущий шаг Содержание Следующий шаг