[Tutor] exercise with classes

Dave Angel d at davea.name
Thu Feb 9 20:53:10 CET 2012


On 02/09/2012 02:23 PM, Tonu Mikk wrote:
> On Mon, Feb 6, 2012 at 12:58 PM, Dave Angel<d at davea.name>  wrote:
>
>> On 02/06/2012 01:24 PM, Tonu Mikk wrote:
>>
>>> Now I get an error:  NameError: global name 'self' is not define.
>>>
>>> Tonu
>>>
>>>
>>>   Put your remarks after the stuff you quote.  You're top-posting, which
>> makes the reply difficult to follow.
>>
>> Use copy/paste to describe an error message.  You retyped the one above,
>> and added a typo.  Include the whole error, which includes the stack trace.
>>
>> If you had followed Nate's advice, you couldn't have gotten that error at
>> all, so you'll also need to post the code that actually triggers the error.
>
>
> Let's try this one more time.  I thought that I would try to make Alan's
> code work.  Here is the version what I have now:
>
> class Printer:
>    def __init__(self,number=0):
>       self.value = number
>    def sayIt(self):
>       print self.value
>
> class MyApp:
>    def __init__(self, aPrinter = None):
>        if aPrinter == None:     # if no object passed create one
>           aPrinter = Printer()
>        self.obj = aPrinter      # assign object
>    def doIt():
>        self.obj.sayIt()         # use object
>
> def test():
>    p = Printer(42)
>    a1 = MyApp()
>    a2 = MyApp(p)   # pass p object into a2
>    a1.doIt(self)   # prints default value = 0
>    a2.doIt(self)   # prints 42, the value of p
>
> test()
>
> When I run it, I get an error:
> Traceback (most recent call last):
>    File "alan_class.py", line 22, in<module>
>      test()
>    File "alan_class.py", line 19, in test
>      a1.doIt(self)   # prints default value = 0
> NameError: global name 'self' is not defined
>
>
Very good.  Now I can see the problem(s).

The immediate problem is that inside function test() (which is an 
ordinary function, not a method), you refer to self, which is not 
defined there.  just omit it there (both times), since the "self" value 
will automatically be supplied when you use the a1.doIt() syntax.

Which takes me to the next problem.  You've defined a method inside 
class MyApp, without supplying the self parameter.  All methods of a 
class will have a 'self' parameter as the first argument (until you get 
to classmethod and staticmethod, which come much later in your 
learning).  You have it everywhere else, but not here.

This is admittedly a confusing aspect of class programming in Python. 
When you call a method, you do not supply an explicit self, it's implied 
by the object you used to get that method.  And in the method, you do 
have to declare an explicit self as the first parameter.  Thus when you 
get error messages, the compiler's concept of how many arguments there 
are, and how many there should be, is confusing.

Trust me when I say there are reasons why this should be, having to do 
with passing bound methods around.  But at this point of your learning, 
it's a confusion with no obvious benefit.

Without trying it, here's what I think those two portions of coee should 
look like:

class MyApp:
    .....
   def doIt(self):
       self.obj.sayIt()         # use object

def test():
   p = Printer(42)
   a1 = MyApp()
   a2 = MyApp(p)   # pass p object into a2
   a1.doIt()   # prints default value = 0
   a2.doIt()   # prints 42, the value of p



-- 

DaveA


More information about the Tutor mailing list