Главная страница
Навигация по странице:

  • Глава Классы и модули6 124 Рис.

  • Глава Классы и модули6 128 Рис.

  • Глава Классы и модули6

  • Приватный или публичный

  • Глава Классы и модули6 132 Рис.

  • Несколько вопросов... 1. Что такое методы и атрибуты класса2. Что такое инкапсуляция3. В чем разница между приватными и публичными эле- ментами...а задач нет

  • Глава Введение в tkinter7

  • Шуман Х. - Python для детей - 2019. # Startwerte festlegen Red (255,0,0)


    Скачать 5.95 Mb.
    Название# Startwerte festlegen Red (255,0,0)
    Дата10.03.2023
    Размер5.95 Mb.
    Формат файлаpdf
    Имя файлаШуман Х. - Python для детей - 2019.pdf
    ТипДокументы
    #977830
    страница9 из 22
    1   ...   5   6   7   8   9   10   11   12   ...   22
    Глава
    Классы и модули
    6
    122
    Рис. 6.6.Результат работы программы: три монстра!
    Теперь я хотел бы расширить все три класса с помощью метода, который имеет возвращаемое значение. Для роди- тельского класса Monster код выглядит так:
    def Type(self) :
    return "Монстр"
    Метод show тоже должен быть расширен. Я сделал новую вер- сию программы, код которой выглядит так (⇒ monster4.py):
    class Monster :
    # Инициализация атрибута def __init__(self, name, character) :
    self.Name = name self.Character = character
    # Метод def Type(self) :
    return "Монстр"
    def show(self) :
    print("Имя: " + self.Name)
    print("Особенность: " + self.Character)
    print("Тип: " + self.Type())
    class GMonster (Monster):
    # Метод def Type(self) :
    return "Дух монстра"

    Наследование
    123
    class SMonster (Monster):
    # Метод def Type(self) :
    return "Душа монстра"
    # Основная программа
    Frank = Monster("Фрэнки", "необычный")
    Frank.show()
    Albert = GMonster("Альберт", "задумчивый")
    Albert.show()
    Sigmund = SMonster("Зигмунд", "веселый")
    Sigmund.show()
    Расширенный метод show()теперь также отображает тип со- ответствующего объекта:
    print("Тип: " + self.Type())
    Помимо прочего, важно, чтобы слово self было помещено перед методом. Это касается всех элементов.
    Теперь у дочернего класса есть все элементы родительского класса и, конечно, его собственные новые атрибуты и мето- ды – в зависимости от того, что было переопределено.
    дочерний родительский
    Атрибут
    +НаследуемыеАтрибуты
    Методы
    +НаследуемыеМетоды
    (
    ) :
    class
    ¾
    Введи код из листинга выше, а затем запусти програм- му. Должно получиться примерно так, как показано на рис. 6.7.

    Глава
    Классы и модули
    6
    124
    Рис. 6.7.Результат работы программы: отображается тип монстра
    Обычно объект Frank вызывает собственный метод Type() в собственном методе show. Интересно, что два других объ- екта сначала вызывают унаследованный метод (= show()) и не получают доступ к дочернему (унаследованному) ме- тоду, а обращаются к собственному методу.
    Как узнать, какой метод Type() использовать? Поскольку у них фактически есть два метода с одним и тем же име- нем Type(), они могут выбрать и использовать неправиль- ный метод «по ошибке». В Python существует механизм, благодаря которому автоматически используется дочер- ний метод.
    На самом деле так происходит и в других языках программиро- вания, таких как, например, C++ или Java: программа, подобная приведенной выше, выводит тип Монстр три раза. Только если определить методы Type() по-разному, код будет работать авто- матически, как в Python. Почему так происходит?
    Существует два способа вызова метода. Обычно в той позиции, где вызывается метод, задается начальный адрес. Этот параметр определяет, какой метод используется. Или ты помечаешь пози- цию вызова с помощью заполнителя. Только во время запуска программы будет использоваться адрес соответствующего ме- тода.

    Модули программы
    125
    Другие языки программирования:
    Python:
    def show() :
    def show() :
    фиксированный адрес заполнитель нормальный метод виртуальный метод
    Это виртуальные методы. В то время как в других языках про- граммирования такие методы имеют метку virtual, все методы в Python по умолчанию виртуальны.
    Модули программы
    Исходный код будет только увеличиваться в объеме со вре- менем. Эта программа не слишком велика, но представь, что ты захотел расширить код на нужное приложение или реализовать дополнительный функционал. Тогда код мож- но разделить на несколько файлов – модулей.
    moster.py mosterlab.py
    Определение класса с помощью атрибутов и методов
    Определение класса с помощью атрибутов и методов
    Основная программа: создание и использование объекта
    Ctrl+X
    Ctrl+V
    Давай создадим новый файл, в котором мы сможем сохра- нить определения классов. В предыдущем файле остается только основная программа.
    ¾
    Убедись, что последняя версия программы открыта.
    Создай новый файл в среде разработки Python (IDLE), щелкнув мышью по пункту
    File (Файл) в строке меню, а затем выбрав пункт
    New file (Создать файл) (или на- жав сочетание клавиш
    Ctrl+N).

    Глава
    Классы и модули
    6
    126
    ¾
    Перейди в файл с кодом программы, выдели целиком определения классов монстров и вырежи их (нажав со- четание клавиш
    Ctrl+X) (рис. 6.8). Затем перейди в окно нового файла и нажми сочетание клавиш
    Ctrl+V, чтобы вставить скопированный код.
    Рис. 6.8.Определения классов монстров выделены
    ¾
    Сохрани оба файла, первый (старый) под новым име- нем (у меня это monster5.py). Новый файл назовем mon­
    sterlab.py.
    Скопированный код теперь находится в файле модуля:
    class Monster :
    # Инициализация атрибута def __init__(self, name, character) :
    self.Name = name self.Character = character

    Модули программы
    127
    # Метод def Type(self) :
    return "Монстр"
    def show(self) :
    print("Имя: " + self.Name)
    print("Особенность: " + self.Character)
    print("Тип: " + self.Type())
    class GMonster (Monster):
    # Метод def Type(self) :
    return "Дух монстра"
    class SMonster (Monster):
    # Метод def Type(self) :
    return "Душа монстра"
    Разумеется, старая программа без определения классов больше не работает. Но как основная программа узнает, где теперь находятся определения классов?
    moster.py mosterlab.py import mosterlab
    Основная программа: создание и использование объекта
    Классы, с которыми мы работали раньше, определены в од- ном модуле, который импортируется в программу. Это вы- глядит так:
    import mosterlab
    Заверши код программы, вставив эту строку кода вверху.
    Затем запусти программу.
    Тебя удивило сообщение об ошибке? Так или иначе компью- тер не узнаёт класс Monster (и, разумеется, два других дочер- них класса) (рис. 6.9).

    Глава
    Классы и модули
    6
    128
    Рис. 6.9.Ошибка определения имени Monster
    Как сообщить компьютеру, что мы уже импортировали со- ответствующий модуль? Недостаточно просто импортиро- вать модуль, также нужно указать его имя, если ты хочешь использовать некий код из этого модуля (например, функ- цию). Давай сделаем это здесь (⇒ monster5.py):
    import monsterlab
    # Основная программа
    Frank = monsterlab.Monster("Фрэнки", "необычный")
    Frank.show()
    Albert = monsterlab.GMonster("Альберт", "задумчивый")
    Albert.show()
    Sigmund = monsterlab.SMonster("Зигмунд", "веселый")
    Sigmund.show()
    Поместив перед именем каждого класса имя модуля, из которого происходит класс, компьютер не будет делать ошибок.
    ¾
    Исправь исходный код основного модуля, затем запус- ти программу.
    Теперь все работает (рис. 6.10).

    Модули программы
    129
    Рис. 6.10.Ошибка исправлена
    Наша семейка монстров готова, но не все еще идеально.
    Во-первых, существует множество атрибутов и методов, которые могут быть согласованы в обоих классах – в зави- симости от твоего воображения. Займись этим.
    А тем временем я хотел бы внести несколько потенциаль- ных улучшений, чтобы основная программа стала чуть бо- лее элегантной. Если мы немного изменим строку кода, отвечающую за импорт модуля, мы сможем сократить код ниже (⇒ monster6.py):
    from monsterlab import *
    # Основная программа
    Frank = Monster("Фрэнки", "необычный")
    Frank.show()
    Albert = GMonster("Альберт", "задумчивый")
    Albert.show()
    Sigmund = SMonster("Зигмунд", "веселый")
    Sigmund.show()
    Вместо импорта всего модуля мы лишь извлекаем отдель- ные классы, обозначенные звездочкой (*) после слова im­
    port
    . Также может использоваться и такая строка:
    from monsterlab import Monster
    Но тогда программа будет работать только для объекта класса, потому что ссылка на вызов monsterlab указана до вызова класса.

    Глава
    Классы и модули
    6
    130
    import from import
    Модуль
    Модуль
    Элемент
    Таким образом, ты можешь интегрировать полный модуль или его части. И если ты хочешь извлечь все элементы, прос то укажи звездочку:
    from Modul import *
    На первый взгляд кажется, что это сложнее и лучше – прос- то импортировать модуль. Но разница в том, что тебе боль- ше не нужно перечислять имена классов в модуле. Также ты можешь сократить объявление объекта – вот так:
    Frank = Monster("Фрэнки", "необычный")
    Albert = GMonster("Альберт", "задумчивый")
    Sigmund = SMonster("Зигмунд", "веселый")
    Приватный или публичный?
    Остается недостаток, который ты даже не заметил вначале и, возможно, никогда не заметил бы. После создания объ- екта, такого как Frank, можно напрямую получить доступ к атрибутам внутри объекта (⇒ monster7.py):
    Frank = Monster("Фрэнки", "необычный")
    print(Frank.Name);
    print(Frank.Character)
    print(Frank.Type())
    Что не так? А вот что. В нашем примере ничего страшного нет, но представь себе определение более сложных классов, которые имеют много атрибутов. Часто нежелателен пря- мой доступ к атрибутам извне. Потому что в зависимости от уровня доступа можно изменить значение атрибута.
    В случае с многочисленными объектами может случиться так, что что-то изменилось, хотя не должно было. И найти такую ошибку часто бывает нелегко.
    Вернемся к термину, который я упомянул в начале: ин- капсуляция. Ее также можно назвать замкнутостью и защи- той от внешнего доступа. В нашем случае достаточно полу- чить доступ к методу show(), и ты получишь доступ ко всему

    Приватный или публичный?
    131
    остальному коду, т. к. он является внутренним. А нужно ли его менять с наружным доступом?
    Давай посмотрим, как Python защищает атрибуты и мето- ды от внешнего доступа. Для этого нам нужно войти в мо- дуль monsterlab.
    ¾
    Открой файл monsterlab.py и сохрани его под именем
    monsterlabx.py.
    Затем тебе нужно добавить два символа подчеркивания (_) для каждого из атрибутов Name и Character, а также метода
    Type()
    :
    class Monster :
    # Инициализация атрибута def __init__(self, name, character) :
    self.__Name = name self.__Character = character
    # Метод def _Type(self) :
    return "Монстр"
    def show(self) :
    print("Имя: " + self.__Name)
    print("Особенность: " + self.__Character)
    print("Тип: " + self.__Type())
    class GMonster (Monster):
    # Метод def __Type(self) :
    return "Дух монстра"
    class SMonster (Monster):
    # Метод def __Type(self) :
    return "Душа монстра"
    Импортируем новый модуль в основную программу и со- ответствующим образом настроим имена (⇒ monster8.py):
    from monsterlabX import *
    # Основная программа
    Frank = Monster("Фрэнки", "необычный")
    print(Frank.__Name);
    print(Frank.__Character)
    print(Frank.__Type())
    Запуск программы выдаст сообщение об ошибке (рис. 6.11):

    Глава
    Классы и модули
    6
    132
    Рис. 6.11.Ошибка: не обнаружены атрибуты объекта
    Хотя _Name (а также _Character и _Type) четко определены и модуль импортирован, основная программа не может по- лучить доступ к этим элементам. Потому что рассматрива- емые атрибуты и метод Type теперь считаются закрытыми.
    И именно этого мы и хотели достичь.
    В Python применяется следующее правило: если ты добавляешь к имени класса два символа подчеркивания, элемент становит- ся закрытым. В противном случае каждый элемент считается публичным. Доступ к публичным элементам можно получить из любой позиции, но в пределах объекта. (Вспомни о доступности глобальных и локальных переменных.)
    ¾
    Чтобы попробовать новый модуль, тебе нужно изме- нить только первую строку в исходном коде monster6.py
    (если ты назвал свой модуль иначе, разумеется, указы- вай свое имя):
    from monsterlabX import *
    Запуск программы заканчивается горьким разочаровани- ем (рис. 6.12). Что происходит?

    Приватный или публичный?
    133
    Рис. 6.12.Все монстры стали одного типа
    Теперь дочерние классы Monster забыли про свой тип и ис- пользуют родительский. Поэтому, очевидно, нельзя ска- зать, что программа стала лучше. Итак, все элементы долж- ны быть определены заново?
    Улучшение было своего рода «промежуточным». Взгляни на решение, которое предоставляет Python (⇒ monsterlabx.py):
    class Monster :
    # Инициализация атрибута def __init__(self, name, character) :
    self.__Name = name self.__Character = character
    # Метод def _Type(self) :
    return "Монстр"
    def show(self) :
    print("Имя: " + self.__Name)
    print("Особенность: " + self.__Character)
    print("Тип: " + self._Type())
    class GMonster (Monster):
    # Метод def _Type(self) :
    return "Дух монстра"
    class SMonster (Monster):
    # Метод def _Type(self) :
    return "Душа монстра"
    Смотри внимательно, чтобы увидеть разницу: теперь метод
    Type()
    имеет только одно подчеркивание (_). И вот разница между соответствующими параметрами доступа (табл. 6.1).

    Глава
    Классы и модули
    6
    134
    Таблица 6.1. Типы доступа
    Тип
    Имя
    Доступ
    Public
    (публичный)
    Без подчеркивания
    В любом месте
    Protected
    (защищенный) С одним подчеркиванием
    В дочерних классах
    Private
    (приватный)
    С двумя подчеркиваниями
    Только внутри объекта
    Внеси изменения, а затем запусти программу еще раз. (Ты можешь скачать все файлы примеров с сайта dmkpress.com
    .)
    Теперь, как раньше, все монстры знают свой тип. Снаружи ты не можешь получить доступ к методу, если только он не касается класса Monster. (Таким образом доступ к методу остается «защищенным».)
    Подведение итогов
    Вот и закончилась очередная глава. Ты написал собствен- ные классы и создал собственные объекты. Однако ты еще не гуру программирования (все самое интересное еще впе- реди). Посмотрим, что ты узнал о Python.
    class
    Определяет класс self
    Ссылка на объект или класс
    _init
    Метод инициализации from
    Импортирует отдельные элементы модуля
    *
    (звездочка)
    Доступ ко всем элементам модуля pass
    Пустая строка, отображающая пустую структуру
    __
    Определяет приватный элемент
    _
    Определяет защищенный элемент
    Связывает объект с атрибутом или методом
    Несколько вопросов...
    1. Что такое методы и атрибуты класса?
    2. Что такое инкапсуляция?
    3. В чем разница между приватными и публичными эле- ментами?
    ...а задач нет

    135
    7
    Введение в tkinter
    До сих пор мы ограничивались вводом кода вручную, но в операционной системе Windows мы привыкли к чему-то большему. Мы используем графический интерфейс, откры- ваем меню, щелкаем по окнам с кнопками, изображениям и полям ввода. Но наши проекты на Python до сих пор были невзрачными, без красивого интерфейса. Теперь это нужно изменить. Ты можешь сделать это с помощью окон, кнопок и т. д.
    Итак, в этой главе ты узнаешь:
    
    что такое tkinter;
    
    об элементах Label и Button;
    
    как работать с событиями;
    
    что такое компоновка окон;
    
    о диалоговых окнах.
    Создаем окно
    Работая с интерфейсом IDLE, мы не использовали многие компоненты, которые содержит операционная система
    Windows. Было бы круто вывести хотя бы одно диалоговое окно на экран. И если нам это удастся, мы заполним это окно разными компонентами.

    Глава
    Введение в tkinter
    7
    136
    Что такое компоненты? Это объекты, которые обычно использу- ются для управления программой. Например, кнопки (Button), меню и метки (Label). Виджеты тоже относятся к компонентам tkinter
    Разумеется, нам нужен модуль, который мы должны снача- ла импортировать:
    import tkinter
    Модуль tkinter содержит все компоненты, необходимые для создания графического пользовательского интерфейса.
    Особенностью модуля является то, что он работает незави- симо от того, что делает операционная система.
    Кстати, слово tkinter является аббревиатурой для Toolkit inter-
    face инструменты для разработки интерфейсов. Модуль содер- жит инструменты для разработки так называемого GUI – Graphical
    User Interface – графического пользовательского интерфейса.
    Наша первая графическая программа очень короткая:
    import tkinter
    Window = tkinter.Tk()
    Если ты запустишь этот код, то увидишь окно, показанное на рис. 7.1.
    Рис. 7.1.Созданное окно
    Сначала создается объект окна, который запускается на- жатием функцией Tk(). Это основной класс модуля tkinter.
    Важно, что имя Tk написано с прописной буквы «T», а слово tkinter со строчной «t».

    Создаем окно
    137
    ¾
    Создай новый файл, напиши исходный код и запусти программу.
    Как насчет приятного приветствия, как мы это делали в главе 1? Воспользуемся компонентом, называемым Label.
    ¾
    Обнови исходный код, а затем перезапусти программу
    (⇒ window1.py):
    import tkinter
    Window = tkinter.Tk()
    Display = tkinter.Label(Window, text="Привет!")
    Display.pack()
    Функция Display создает объект Label, первый параметр указывает на окно, в котором должно отображаться содер- жимое Label, а второй представляет собой текст, который надо отобразить. Все это «обернуто», так сказать, в метод pack
    . Без этой инструкции ты ничего не увидишь в окне
    (рис. 7.2).
    Рис. 7.2.Приветствие в окне
    Окно стало еще более маленьким, чем предыдущее. Это связано с тем, что размер окна адаптируется под размер компонентов. Позже мы рассмотрим, как можем влиять на размер окна.
    Теперь я хотел бы усложнить программу, чтобы за «при- ветствием» последовал вопрос «как дела?», а также доба- вить две кнопки Button, чтобы окно выглядело следующим образом:
    Рис. 7.3.Усложненная программа
    Выглядит (по-прежнему) не очень красиво, но ключевое слово pack в tkinter гарантирует, что окно занимает столь- ко места, сколько необходимо. Кроме того, все компоненты расположены один за другим. Мы изменим это позже.

    1   ...   5   6   7   8   9   10   11   12   ...   22


    написать администратору сайта