map and self
Calvelo Daniel
dcalvelo at pharion.univ-lille2.fr
Fri Sep 15 14:20:33 EDT 2000
Larry Whitley <ldw at us.ibm.com> wrote:
: I'm having trouble understanding "self" when used within a map(). Here's my
: problem:
: class A:
: def __init__(self):
: self.cnt = 0
: class B:
: def __init__(self):
: self.cntList = []
: for i in range(5):
: self.cntList.append( A() )
: def myprint(self):
: print map( lambda x: self.cntList[x].cnt, range(len(self.cntList)))
[ produces 'NameError: self' ]
You are being bitten by the infamous yet famous scoping rules of Python.
When you write 'lambda x: self.something()', you are actually writing
something resembling
def anonymous_function(x):
self.something()
Now remeber that Python has two scopes: global (module) and local. When
you begin a 'def' you *change* the local scope. Your global scope usually
remains the same.
When you define your 'lambda x:...', you are already in a local scope
where 'self' is duly defined. As soon as you cross the colon in lambda,
so to speak, you forget your previous local scope and start with a fresh
new one, where only 'x' is defined. 'self' is not.
: Yet, when I perform the above actions interactively, it works as expected.
[ demonstrates so ]
: (Note that I left "self" off here since it is inappropriate in outside the
: context of a class.)
That's why it works.
Keep in mind that "self" has nothing special to it. It is an identifier
that happens to receive the instance object when called within a method.
: So, my question... How do I get around the NameError: self problem and use
: this sort of thing in methods internal to a class?
You have to "pass" self to the new scope. Change your print above to:
print map( lambda x,self=self: self.cntList[x].cnt,\
range(len(self.cntList)))
and it should work (untested). Notice the 'self=self': the first 'self' is
the formal parameter, the second is the value of the 'self' identifier.
HTH, DCA
-- Daniel Calvelo Aros
calvelo at lifl.fr
More information about the Python-list
mailing list