scoping questions

Phil Frost indigo at bitglue.com
Wed Jun 2 14:26:07 EDT 2004


In Python, all objects are represented by structures allocated on the
heap. Whenever you pass python objects around in python, you are
actually passing references to those objects.

However, python has a notion of objects being "mutable" or "immutable".
Some objects are mutable, such as lists, dictionaries and classes.
Others are immutable, such as strings, tuples, and integers.

A namespace in python is implemented internally as a dictionary. There
are ways to access this dictionary directly from python, although I'd
have to read the manual to see how, as it's not something you need to do
often. A function has its own namespace. When you have something such as
this:

def fu(bar):
  bar = 3

you are not derefrencing 'bar', and assigning 3 to it. Rather, you are
changing the namespace of fu (a dictionary, actually) to map "bar" to 3.
This explains your first example.

However, if you use a mutable type, as you did with a file in the latter
example, it is possible that an object passed as a parameter might be
modified when passed as a parameter to a function. Using lists as an
example:

def fu(bar):
  bar.append(1)

l = []
fu(l)
print l
# l = [1]

In this case, 'bar' is a reference to 'l'. By calling append(), 'bar'
remains a reference to 'l', but the contents of 'l' are changed. Because
'l' and 'bar' reference the same object, the changes are visible in both
places. This is possible because a list is a mutable type.

On Wed, Jun 02, 2004 at 05:47:31PM +0000, David Stockwell wrote:
> Hi,
> 
> Another of my crazy questions.  I'm just in the process of learning so bear 
> with me if you can.   I actually ran it....  with two test cases
> 
> TEST CASE 1:
> Say I have the following defined:
> --- beginning of code snippet ----
> 
> def me(aFile):
>   """
>     Note I am testing scoping
>   """
>   aFile = 'hello world'
>   print aFile
> 
> 
> 
> aFile = open('/tmp/test','r')
> me(aFile)
> data = aFile.read()
> print data
> 
> ------ end of code snippet ----
> my test file has a sentence 'This is a test of the /tmp/test file'
> 
> When I run it I observed this output:
> hello world
> This is a test of the /tmp/test file
> 
> Now what this means to me and this is where I need your help:
> 
> When I call the 'me' function, its passing a reference to my original aFile 
> variable.
> Inside the me function, I'm guessing it is now  a new reference to the same 
> original aFile contents.  When I assign it to a simple string, it simply 
> changes the local reference to point to that string.  Since its a copy of 
> the reference, it doesn't affect the caller's value.
> 
> In essence if i understand correctly
> 
> At the global scope I have
> 
> variable aFile that points to an instance of a 'file'
> 
> Inside the me function scope I have
> a parameter named aFile that is a local copy of the original reference of 
> what global::aFile was pointing to.
> Essentially local::aFile is pointing to a file object
> 
> At this point I have two references to the file object.
> 
> When I assign the new value to aFile (local) it simply does the assignment. 
> The global reference is untouched.
> 
> I would sort of expect this behavior as I am not returning anything
> 
> If test #1 is true, then test case 2 boggles me a bit
> 
> TEST CASE 2:
> -------
> def me(aFile):
>   """
>     Note I am testing scoping
>   """
>   aFile = 'hello world'
>   print aFile
> 
> 
> def me2(dog):
>   """
>     Note I am testing scoping
>   """
>   print "Inside me2"
>   dog.close()
> 
> 
> aFile = open('/tmp/test','r')
> me(aFile)
> data = aFile.read()
> print "test1", data
> aFile.close()
> aFile = open('/tmp/test','r')
> 
> me2(aFile)
> print "test2", aFile.read()
> =====
> 
> It bombs out on the last line because aFile was closed in the function 
> 'me2'.
> 
> Perhaps the way to explain it is that Inside me2 when my copy of the 
> original reference is made, I have a global and local variable both 
> referencing the same 'object'.   I am able to do operations in the local 
> me2 scope and have them effect the behavior of the global scope.
> 
> Its just a bit confusing because python is apparently smart enough to 
> realize that my action on the local reference hasn't redefined the 
> capability of the global so it has allowed this to occur on the actual 
> global file referenced object. (as opposed to just a local copy).  And I 
> didn't return anything....
> 
> 
> I'm just confused a bit here.... Perhaps someone can clarify
> 
> Thanks
> 
> David
> -------
> Tracfone: http://cellphone.duneram.com/index.html
> Cam: http://www.duneram.com/cam/index.html
> Tax: http://www.duneram.com/index.html




More information about the Python-list mailing list