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