[Tutor] OOP question

Steven D'Aprano steve at pearwood.info
Tue Jan 18 22:38:00 CET 2011


Ben Ganzfried wrote:
> Hey guys,
> 
> I'm trying to get a version of Roulette working and I had a quick question.

There's a quick answer and long answer. The quick answer is, you have to 
refer to self.odds, not just odds. The long answer is below:

> Here is my code:
[...]
> Now whenever I try to call the winAmount method, I get the following error:
> NameError: global name 'odds' is not defined
> 
> I'm wondering the following: I had thought that by initializing "odds" in
> the first initialization method that "odds" should then be accessible to all
> the other methods in the class.  This does not seem to be the case.  So what
> is the ideal fix?  On the one hand I still need to initialize "odds",
> right?  But if "odds" is within the initialization method, how else can it
> be accessed by the other methods?

The relevant method here is:

     def winAmount(self, amount):
         return odds*amount

This tells Python:

"Look up the value for the name 'odds', and the name 'amount', multiply 
the two values, and return the result."

How does Python look up names? It looks in *namespaces* -- first it 
looks in the function's local namespace (local variables like 'amount'), 
then it looks in the global namespace (global variables), and finally it 
looks in the builtin namespace (built-in functions like len, min, max, 
etc). You get a NameError, because there is no name 'odds' in any of 
those namespaces.

To look for attributes, you have to look in the instance namespace:

         return self.odds*amount

This looks up 'self' as above, and finds it as a local variable. Then it 
looks for an attribute 'odds' inside self, which is the result you want.

This is much more general than just methods inside classes. The same 
process occurs whenever you use attribute access:

import math
math.sin(x)

s = "hello sailor"
s.upper()



-- 
Steven


More information about the Tutor mailing list