[Tutor] Proper uses of classes
Dave Angel
davea at davea.name
Fri Apr 5 11:42:46 CEST 2013
On 04/04/2013 01:01 PM, frank ernest wrote:
> Sorry about the indentation guys my mail service atomatically removed it when I pasted the text (I tried to fix it by hand but it was hard to tell if I was sucessful.)
> I was tring to create a list object (self) and change it using the list methods and some additional ones I will define in my class.
> I wanted to create some varibles which I pass to most if not all of my methods. Two of my variables are to be passed to the class apon creation of the object and then they in turn are to be passed to all or most of the methods I create (a, b in this case.) If I make a, b nonlocal I get the message that they are already nonlocal.
> I will need for debuging purposes to print my object in random places in my class.
> If I did this:
>> self.a = aWhat would that create (I'm thinking local variable?)?
No. a is a local variable, since it was passed as an argument. self.a
is an attribute of the alist instance.
>
> class alist(): def __init__(self, b, a): self.mylist = list() self.mylist.append(b) self.a = a + b def appendit(self): #I need to get a in hear without passing #it in; it must come from the init method. self.mylist.append(self.a) #(I hope I've updated the code well, I can't test it from this computer.)PS: This is not the real code that I'm Emailing: I thought I'd be better off with some simpler code that produces the same errors.
>
>
Your mail service is just broken, at least for use here. This is a text
forum, and your mail has an empty text body. So each of our mail
readers has to try to reconstruct the text from html nonsense. You can
see the result above of what Thunderbird does.
The following is what I think you posted.
class alist():
def __init__(self, b, a):
self.mylist = list()
self.mylist.append(b)
self.a = a + b
def appendit(self):
#I need to get a in hear without passing
#it in; it must come from the init method.
self.mylist.append(self.a)
#(I hope I've updated the code well, I can't test it from this
computer.)
There are lots of terminology problems which will stop you from
understanding what's going on.
"I wanted to create some varibles which I pass to most if not all of my
methods"
"Variables" passed to methods are called arguments, or parameters, and
that's NOT what you're trying to do. You're trying to have the
__init__() method "remember" those values. When you write "self.a ="
you are creating an "instance attribute" which is visible to all methods
on that instance. Other methods can access that instance attribute by
referring to it as self.a Not by "global" not by "nonlocal". Those
are very different. A local variable is also different, as is a class
attribute. You need to study up on each of these terms, and see what
the differences are in terms of lifetime, visibility, duplication, etc.
More on that later.
Now, the appendit() method is nonsensical, but perhaps it was just a
sample. Each time it's called, it'll append the same value a to the list.
Perhaps you'd be more comfortable if you wrote a __str__() method. That
way, when you try to print an instance, it'll do what you say, rather
than some default. Typically, it should do something with each
attribute that was initialized by __init__(). (untested)
def __str__(self):
res = "mylist attribute is" + str(self.mylist) + "\n"
res += "a is " + str(a) + "\n"
return res
Now you can exercise your class, and print out the results as often as
you like: (untested)
obj1 = alist(3, 47) # creates an instance of alist
print(obj1) # prints it
obj2 = alist(12, 9) # creates a second instance of alist, with its own
self.mylist and self.a, different from those in obj1
print(obj2)
obj1.append() #will take the particular list in obj1, and append the
saved self.a value
print(obj1)
obj2.append()
obj2.append()
print(obj)
Now, a brief, informal summary of all the different kinds of
"variables." A global variable is defined at the outer scope of a
module, and should mostly be constants, for sound engineering reasons.
The global keyword, used only inside a function, declares that a
particular variable that looks like it ought to be local, in fact is
global. The keyword applies only to that particular function.
A local variable is defined and used within a function (or method), and
vanishes entirely when the function returns. The formal parameters of
the function are locals as well.
A class attribute belongs to the class, and there's only one of them,
regardless of how many instances that class has.
An instance attribute exists separately in each instance of a class. It
should (my preference) be initialized in the __init__() method so that
every instance has the same attributes, even if it's just
self.att = None
A nonlocal variable is probably beyond what you need to know at the
present, but it's one that's either global, or in some other function.
When you say xxxx.yyyy the meaning of that depends entirely on what
xxxx is defined as. If xxxx is a class, then yyyy is an attribute of
that class. If xxxx is an instance, then yyyy might be an instance
attribute (usually) or a class attribute (if no instance attribute by
that name). If xxxx is a module, then yyyy is a global in that other
module.
The name self is a convention, but a very useful one there's no
advantage in breaking. Most methods take self as their first argument,
and it refers to the object that method is called with. In the specific
case of __init__() method, that object is newly created. In nearly all
other cases, it's the object specified to the left of the method name,
like obj1.appendit()
There are a few other tricks that might matter, but this should get you
going. Play with all these concepts, and become attuned to it. Only
then should you try to do things like inherit from list.
--
DaveA
More information about the Tutor
mailing list