On 07/26/2016 11:38 PM, Ben Finney wrote:
Jim Byrnes <jf_byr...@comcast.net> writes:

So I decided to give it another try. When I got to the chapter on
tkinter I decided to solve all the exercises using OOP even though the
book solutions did not use OOP.

Hmm, that sounds ill advised.

OOP is one tool among many; trying to apply it where it's a poor fit
will result in bad design and probably avoidable errors.

When learning to use a hacksaw, trying to solve everything using that
tool merely to learn it, would be a poor choice.

With anything more complex I would agree. I am simply trying to get myself thinking about how OOP works and there aren't enough exercises in the book calling for OOP to give me much repetition.

# exer2.py

import tkinter

class Count:

  def __init__(self):
    ''' Increment a button labeled 0, by 1 with each click '''
    […]
    self.count_btn = tkinter.Button(self.frame, textvariable=self.label,
      command=lambda: self.increment(self.label ))

Here you address the ‘self.increment’ name, which should work.

  def increment(self, label):
    count = int(self.label.get())
    self.label.set(str(count + 1))

This is the method that an instance will address via ‘self.increment’.

In exer2.py if I do command=lambda: increment(self.label)

The lambda expression creates a function, and that function then behaves
like any other function. Within that function, the name ‘increment’ is
not defined; within the scope where the function was defined, the name
‘increment’ is also not defined. Within the global scope the name
‘increment’ is not defined.

So yes, you'll get NameError from that code.

Why do I get this error?  The situations look the same to me

The difference is that when you invoke ‘self.instance’, the lookup of
‘self’ succeeds because it's defined within the function (you defined it
in the parameters of ‘__init__’, so ‘__init__’ knows that name when it
is running).

You never defined the name ‘increment’ within the function, nor within
the global scope. And you shouldn't because there's no need: you access
the instance's own method by accessing the instance first: you ask for
“the ‘instance’ attribute from the ‘self’ object”: ‘self.instance’.


OK thank you.

Regards,  Jim


_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to