[Tutor] the class struggle

Kirby Urner urnerk@qwest.net
Thu, 29 Nov 2001 16:36:59 -0800


At 05:09 PM 11/29/2001 -0600, Rob McGee wrote:
>Hi all, I am a python 2.0 beginner. I'm trying to write a silly little
>program. Actually I *did* write it using a function definition, but I
>wanted to be object-oriented, so I'm trying to use a class instead. This
>isn't working out.
>
>{code}
>import random
>
>def myObject(name):
>   variable = name
>   anotherOne = anotherValue
>   if name in someList:
>     nextVar = this
>     lastOne = that
>   else:
>     nextVar = random.randrange(10, 70)
>     lastOne = random.randrange(5, 15)
>{/code}


Rob, this function is not self contained as written.
You've defined a lot of the variables in the shell,
off camera (so to speak) and these are available as
global variables.  You also appear to be assigning
to globals, versus returning values.  That's called
relying on side-effects and its a major ingredient
in messy, hard-to-debug code.  Not to worry.

If I simply cut and paste your code to my shell,
including the import statement, it dies (not
surprisingly):

   >>> myObject("jim")
   Traceback (most recent call last):
     File "<pyshell#5>", line 1, in ?
       myObject("jim")
     File "<pyshell#4>", line 3, in myObject
       anotherOne = anotherValue
   NameError: global name 'anotherValue' is not defined

I have to make up values for a lot of the variables
in your code before it'll work.  Generally, functions
shouldn't be so dependent on their environment -- critical
external stuff should mostly come through the "front door",
as passed arguments.  And whatever the function does, its
final results should go out the "back door" using a
return statement.

>That works. I got a complete and working (although not very polished)
>program using a function like that. It's worthy of the Useless Python
>site, for sure. :)

I think as a standalone, it's not ready for Useless, because
of it's heavy reliance on stuff you've defined out-of-scope.
Also, it's not documented (gotta have comments explaining
the purpose of the function, before it goes to the internet).

>{code}
>import random
>
>class myObject(name):
>   def __init__(self, name):
>     variable = name
>     anotherOne = anotherValue
>     if name in someList:
>       nextVar = this
>       lastOne = that
>     else:
>       nextVar = random.randrange(10, 70)
>       lastOne = random.randrange(5, 15)
>{/code}

The first problem here is you're saying your class inherits from
some other parent class named 'name'.  Unless you've actually
written such a class, you should not have any parents in the
class declaration, i.e. just go:

   class myObject:

to start.

Beyond that, it should compile as is.  I cut and pasted your
code to my shell and it took.

I was even able to instantiate an object

   omy = MyObject("Duh")

but that's because I've already made anotherValue and
SomeList global, i.e. I defined them higher up in the
session (or module).  If I go:

   >>> del anotherValue

and try to instantiate another object of class myObject:

   >>> omy = myObject("Duh")
   Traceback (most recent call last):
     File "<pyshell#20>", line 1, in ?
       omy = myObject("Duh")
     File "<pyshell#19>", line 4, in __init__
       anotherOne = anotherValue
   NameError: global name 'anotherValue' is not defined

>That doesn't work. "SyntaxError: invalid syntax" on the "if"
>(caret goes under the "f".) I tried adding "self." in front
>of the class instance variables just for fun. Same thing.

I don't understand this error exactly.  I can't reproduce it.
Are you in IDLE, and do your key words colorize?  Is your
'if' orange?

It could be a consequence of trying to inherit from
'name' as a parent class.  You may have 'name' defined
as a global elsewhere...

Back to my original comment, your function 'works' in the
sense that it assigns to global variables.  But this
isn't the way you'll want to assign to globals using
functions.  You should make your function return a value,
or a tuple of values, and let the internal variables
vanish when the function is complete.  Like this:

def mynumber(number, SomeList):
    if number in SomeList:
        return name
    else:
        return random.randrange(10,70)

Then, when using this function, go:

  >>> variable = mynumber(71,[70,71,72])
  >>> variable
  71
  >>> anotherValue = mynumber(73,[70,71,72])
  >>> anotherValue
  46


>I have read the tutorial and what I could find in the other docs about
>classes. I rented Ivan Van Laningham's "24 Hours" book at the local
>bookstore / coffee shop (I always buy a cup of coffee :) and thought I
>I was beginning to understand.

I think you are.  But I'd recommend mastering functions first,
moving to objects next.


>I guess not.
>
>I tried commenting out the if/else lines and making a little function to
>test it out, and now everything after this accursed class definition is
>a SyntaxError.
>
>Is there something online with another description of using class
>definitions? Or perhaps can you fine folks point me in the right
>direction?
>
>BTW, except for classes I think I'm understanding things pretty well. I
>am able to make python do what I set out to do.

But given you're doing a lot of global variable manipulation,
as side-effects of functions, functions which don't explictly
return values, plus heavily depend on environmental values
not passed in as arguments, I'd recommend you slow down and
get a better grip.  Getting the basics down before moving on
can save you a lot of 'unlearning' in the future.

There's no hurry (is there?).

Kirby