Найти - Пользователи
Полная версия: Пример из книги М.Лутца. Программирование на питон 4 изд. Наследование в классах.
Начало » Python для новичков » Пример из книги М.Лутца. Программирование на питон 4 изд. Наследование в классах.
1
Chesheer
Добрый день. Я только учусь поэтому просьба сильно не пинать. Пасиб.
Вопрос в следующем.

Изучаю книгу М.Лутца Программирование на Питон 4е издание. Там реализован пример создания GUI состоящий из нескольких модулей:
- Пример 10.2. PP4E\Gui\Tools\guimixin.py (стр.770)
- Пример 10.3. PP4E\Gui\Tools\guimaker.py(стр.775)
- Пример 10.5. PP4E\Gui\ShellGui\shellgui.py (стр 787)
- Пример 10.6. PP4E\Gui\ShellGui\mytools.py (стр. 789)
- Пример 10.7. PP4E\Gui\ShellGui\packer.py (стр. 791)
- Пример 10.8. PP4E\Gui\ShellGui\unpacker.py (стр. 791)
- Пример 10.9. PP4E\Gui\ShellGui\formrows.py (стр. 794)
- Пример 10.10. PP4E\Gui\ShellGui\packdlg.py (стр. 794)
- Пример 10.11. PP4E\Gui\ShellGui\unpkdlg.py (стр. 796)
(модули я добавил в прикрепленные файлы).

Теперь та часть которая вызвала затруднения.
Атрибут setToolBar класса ShellGui ссылается на атрибут fetchCommands класса DictMenuGui, причем DictMenuGui не является супер классом класса ShellGui(как я думаю), но код работает. Подскажите пожалуйста почему setToolBar видит fetchCommands. Ниже приведена часть этого кода. Вся программа в приложении.
Shellgui.py
from tkinter import *
from guimixin import GuiMixin
from guimaker import *
class ShellGui(GuiMixin, GuiMakerWindowMenu): 
    def start(self): 
        self.setMenuBar() 
        self.setToolBar()
        self.master.title("Shell Tools Listbox")
        self.master.iconname("Sell Tools")
    def handleList(self, event):
        label = self.listbox.get(ACTIVE)
        self.runCommand(label)
    def makeWidgets(self):
        sbar = Scrollbar(self)
        list = Listbox(self, bg='white')
        sbar.config(command=list.yview)
        list.config(yscrollcommand=sbar.set)
        sbar.pack(side=RIGHT, fill=Y)
        list.pack(side=LEFT, expand=YES, fill=BOTH)
        for (label, action) in self.fetchCommands():
            list.insert(END, label)
        list.bind('<Double-1>', self.handleList)
        self.listbox = list
    def forToolBar(self, label):
        return True
    def setToolBar(self):
        self.toolBar = []
        for (label, action) in self.fetchCommands():            # Здесь ссылка на атрибут fetchCommands 
            if self.forToolBar(label):                                    # который находится в другом классе 
                self.toolBar.append((label, action, dict(side=LEFT))) 
        self.toolBar.append(('Quit', self.quit, dict(side=RIGHT)))
    def setMenuBar(self): 
        toolEntries = [] 
        self.menuBar = [ 
            ('File', 0, [('Quit', -1, self.quit)]),
            ('Tools', 0, toolEntries) 
            ]
        for (label, action) in self.fetchCommands():         # И здесь тоже
            toolEntries.append((label, -1, action))
class DictMenuGui(ShellGui):
    def fetchCommands(self):
        return self.myMenu.items()
    def runCommand(self, cmd):
        self.myMenu[cmd]()
class ListMenuGui(ShellGui):
    def fetchCommands(self):
        return self.myMenu
    def runCommand(self, cmd):
        for (label, action) in self.myMenu:
            if label == cmd: action()




FishHook
Chesheer
причем DictMenuGui не является супер классом класса ShellGui
ShellGui наследуется от GuiMixin и GuiMakerWindowMenu.
Вероятно, в дереве наследования какотого из этих классов есть DictMenuGui, либо один из этих классов или их родителей сам по себе реализует такой метод без наследования.
Для того, чтобы унаследовать атрибут, не обязательно быть прямым потомком класса или “интерфейса”, достаточно того, чтобы где-то в дереве наследования этот метод был реализован.
В пайшарме вы можете нажать ctrl-u, когда курсор на методе и перейти к родительскому классу.
Chesheer
FishHook
В пайшарме вы можете нажать ctrl-u, когда курсор на методе и перейти к родительскому классу.
Хм. Спасибо за подсказку. Сейчас попробую.
п.с. GuiMixin не наследует никаких классов, GuiMakerWindowMenu наследует класс Frame.
Chesheer
Ответа я не нашел, но есть предположение. Поправьте если я ошибаюсь. Класс DictMenuGui имеет подкласс TextPak2 который находится в другом модуле и самый нижний класс в иерархии. В TextPack есть такая инструкция. DictMenuGui.init(self). Как я понял эта инструкция создает экземпляр наследующий весь список атрибутов вышестоящих классов. Т.о. при вызове sef.fetchCommands() из ShellGui.setToolBar интерпретатор ищет сначала в атрибутах экземпляра, где он имеется и только потом в атрибутах класса и надклассов. В общем как то так.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB