[Tutor] Help with class in class
Peter Otten
__peter__ at web.de
Sun Sep 9 19:12:03 CEST 2012
leam hall wrote:
> I'm in the O'Reilly Python 2 class, so pointers to learning would be
> better than just answers, please. My brain is a bit slow but needs to go
> forward.
>
> Line 16 calls line 31. Rather, it is supposed to. I'm trying to figure out
> why I get
>
> File "./ch8_project.py", line 31, in change_text_color
> self.text.tag_configure('highlightline', foreground=fg_color)
> AttributeError: 'ch8_Project' object has no attribute 'text'
>
> If line 31 starts with "self." and
>
> File "./ch8_project.py", line 31, in change_text_color
> text.tag_configure('highlightline', foreground=fg_color)
> NameError: global name 'text' is not defined
>
>
> If Line 31 does not start with "self.". I understand the second problem
> but not the first.
>
> What am I missing?
When inside a method you assign to
self.whatever = ...
you are setting an attribute of the class. If you assign to a name
whatever = ...
you are setting a local variable. So
> #!/usr/bin/env python3
>
> from tkinter import *
>
> SIDE = W+E
> ALL = N+E+W+S
>
> class ch8_Project(Frame):
>
> def __init__(self, master=None):
> Frame.__init__(self, master)
> self.file_open("./fred")
> fg_color = "Red"
> self.pack()
> self.add_text_widget( fg_color, self.out_text)
> self.green = Button(root, text="Green",
command=self.change_text_color("green"))
> self.green.pack(side=TOP)
>
> def add_text_widget(self, fg_color, out_text):
> text = Text(root)
in the above line you are making a local variable which will be forgotten
when the method terminates. Change the line to
self.text = Text(root)
do the same for the following lines, and
> text.insert(INSERT, out_text)
> text.tag_configure('highlightline', foreground='red')
> text.tag_add('highlightline', '1.0', 'end')
> text.pack()
>
> def file_open(self, file_name):
> file = open(file_name, "r")
> self.out_text = file.read()
>
> def change_text_color(self, fg_color):
> self.text.tag_configure('highlightline', foreground=fg_color)
the above will no longer complain about a missing attribute.
> root = Tk()
> project = ch8_Project(master=root)
> project.mainloop()
Another problem that caught my attention:
> self.green = Button(root, text="Green",
command=self.change_text_color("green"))
The command argument is supposed to be a function; you are instead assigning
the result of a method call (which is None in this case, but as a side
effect will set the color to green immediately. The simplest fix is to
define a helper function that takes no arguments
...
def change_to_green():
self.change_text_color("green")
self.green = Button(root, text="Green", command=change_to_green)
...
If you already know about lambda you can try to rewrite this using that.
More information about the Tutor
mailing list