Good day. I just learn so please do not kick much. Thank you. The question is as follows.

I am studying the book of M.Lutz Programming on Python 4th edition. There is an example of creating a GUI consisting of several modules:

  • Example 10.2. PP4E \ Gui \ Tools \ guimixin.py (p.770)
  • Example 10.3. PP4E \ Gui \ Tools \ guimaker.py (p.775)
  • Example 10.5. PP4E \ Gui \ ShellGui \ shellgui.py (page 787)
  • Example 10.6. PP4E \ Gui \ ShellGui \ mytools.py (p. 789)
  • Example 10.7. PP4E \ Gui \ ShellGui \ packer.py (p. 791)
  • Example 10.8. PP4E \ Gui \ ShellGui \ unpacker.py (p. 791)
  • Example 10.9. PP4E \ Gui \ ShellGui \ formrows.py (p. 794)
  • Example 10.10. PP4E \ Gui \ ShellGui \ packdlg.py (p. 794)
  • Example 10.11. PP4E \ Gui \ ShellGui \ unpkdlg.py (p. 796)

Here is the part that caused the trouble. The setToolBar attribute of the ShellGui class refers to the fetchCommands attribute of the DictMenuGui class, and DictMenuGui is not a superclass of the ShellGui class (I think), but the code works. Please tell me why setToolBar sees fetchCommands. Below is part of this code. The whole program in the application. Thank you so much for the help.

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() 

    3 answers 3

    If fetchCommands() not defined in either the class or its ancestors, then ShellGui is ShellGui an abstract class: if only DictMenuGui and ListMenuGui objects are created, then fetchCommands() always available.

    I did not read the book and the examples, I only start from the code presented in the question itself, so I don’t know if this interpretation agrees with the author’s intention.

      I did not find the answer, but there is a guess. Correct if I'm wrong. The DictMenuGui class has a subclass of TextPak2 which is in another module and the lowest class in the hierarchy. In TextPack there is such instruction. DictMenuGui. init (self). As I understand this instruction creates an instance that inherits the entire list of attributes of the parent classes. So when calling sef.fetchCommands () from ShellGui.setToolBar, the interpreter searches first for the attributes of the instance and only then for the attributes of the class and superclasses. In general, something like this.

        def fetchCommands (self): now is an attribute of ShellGui and can get the values ​​of the functions of these GuiMixin, GuiMakerWindowMenu classes and also override them well or remove the method from the abstract class