Function parameter scope

2010-07-28 Thread Navkirat Singh
Hi,

I had another question:

What is the scope of  a parameter passed to a function? I know its a very basic 
question, but I am just sharpening my basics :)

def func_something(x)

return print(x+1);

Does x become a local variable or does it stay as a module scoped variable?

Though I think its local, but just want to be sure.

Thanks,
Nav
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Function parameter scope

2010-07-28 Thread Chris Rebert
On Wed, Jul 28, 2010 at 7:00 PM, Navkirat Singh navkir...@gmail.com wrote:
 Hi,

 I had another question:

 What is the scope of  a parameter passed to a function? I know its a very 
 basic question, but I am just sharpening my basics :)

 def func_something(x)

        return print(x+1);

 Does x become a local variable or does it stay as a module scoped variable?

 Though I think its local, but just want to be sure.

Yes, it's indeed local. Also, you may wish to instead direct similar
basic questions to the Python Tutor mailinglist in the future:
http://mail.python.org/mailman/listinfo/tutor

Cheers,
Chris
--
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Function parameter scope

2010-07-28 Thread Steven D'Aprano
On Thu, 29 Jul 2010 07:30:34 +0530, Navkirat Singh wrote:

 Hi,
 
 I had another question:
 
 What is the scope of  a parameter passed to a function? I know its a
 very basic question, but I am just sharpening my basics :)
 
 def func_something(x)
   return print(x+1);
 
 Does x become a local variable or does it stay as a module scoped
 variable?
 
 Though I think its local, but just want to be sure.


Yes, x is local.

However, be careful that Python does not make a copy of arguments passed 
to functions. So the local name refers to the same underlying object as 
the global name, and *modifications* to the *object* will be seen 
everywhere. But *reassignments* to the *name* are only seen locally.



def test(local_name):
print(local_name)
local_name = 2
print(local_name)
print(global_name)

global_name = 1
test(global_name)

= prints 1, 2, 1.



def test(local_name):
print(local_name)
local_name.append(2)
print(local_name)
print(global_name)

global_name = [1]
test(global_name)

= prints [1], [1, 2], [1, 2].


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-21 Thread J Kenneth King
alex23 [EMAIL PROTECTED] writes:

 On Nov 21, 9:40 am, J Kenneth King [EMAIL PROTECTED] wrote:
 Of course, providing a shallow (or deep as necessary) copy makes it
 work, I'm curious as to why the value passed as a parameter to a
 function outside the class is passed a reference rather than a copy.

 You're passing neither a reference nor a copy, you're passing the
 object (in this case a list) directly:

 http://effbot.org/zone/call-by-object.htm

Ah, thanks -- that's precisely what I was looking for.

I knew it couldn't be a mistake; I just couldn't find the documentation
on the behaviour since I didn't know what it was called in the python
world.

Cheers.
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-21 Thread J Kenneth King
Steven D'Aprano [EMAIL PROTECTED] writes:

 On Thu, 20 Nov 2008 18:31:12 -0500, J Kenneth King wrote:

 Of course I expected that recursive_func() would receive a copy of
 weird_obj.words but it appears to happily modify the object.

 I am curious why you thought that. What made you think Python should/did 
 make a copy of weird_obj.words when you pass it to a function?

 This is a serious question, I'm not trying to trap you into something :)

Don't worry, I don't feel trapped in usenet. ;)

It was more of an intuitive expectation than a suggestion that Python
got something wrong.

I was working on a program of some complexity recently and quickly
caught the issue in my tests. I knew what was going on and fixed it
expediently, but the behaviour confused me and I couldn't find any
technical documentation on it so I figured I just didn't know what it
was referred to in Python. Hence the post. :)

I suppose I have some functional sensibilities and assumed that an
object wouldn't let a non-member modify its properties even if they were
mutable.

Of course if there is any further reading on the subject, I'd appreciate
some links.

Cheers.
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-21 Thread Peter Pearson
On Fri, 21 Nov 2008 10:12:08 -0500, J Kenneth King wrote:
 Steven D'Aprano [EMAIL PROTECTED] writes:

 I am curious why you thought that. What made you think Python should/did 
 make a copy of weird_obj.words when you pass it to a function?
[snip]
 Of course if there is any further reading on the subject, I'd appreciate
 some links.

As one relatively new Python fan to another, I recommend following
this newsgroup.  Many important aspects of Python that several books
failed to drive through my skull are very clearly (and repeatedly)
explained here.  Hang around for a week, paying attention to posts
with subjects like Error in Python subscripts (made-up example),
and curse me if you don't find it greatly rewarding.

-- 
To email me, substitute nowhere-spamcop, invalid-net.
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-21 Thread J Kenneth King
Peter Pearson [EMAIL PROTECTED] writes:

 On Fri, 21 Nov 2008 10:12:08 -0500, J Kenneth King wrote:
 Steven D'Aprano [EMAIL PROTECTED] writes:

 I am curious why you thought that. What made you think Python should/did 
 make a copy of weird_obj.words when you pass it to a function?
 [snip]
 Of course if there is any further reading on the subject, I'd appreciate
 some links.

 As one relatively new Python fan to another, I recommend following
 this newsgroup.  Many important aspects of Python that several books
 failed to drive through my skull are very clearly (and repeatedly)
 explained here.  Hang around for a week, paying attention to posts
 with subjects like Error in Python subscripts (made-up example),
 and curse me if you don't find it greatly rewarding.

I do lurk more often than I post and sometimes I help out people new to
Python or new to programming in general. I know how helpful usenet can
be and usually this group in particular is quite special. It's good
advice to read before you post; quite often the question has been
proposed and answered long before it came to your little head (not you
in particular; just general you).

In this case, I was simply lacking the terminology to find what I was
looking for on the subject. In such cases turning to the community seems
like a fairly reasonable way to find clarification. I've only been
programming in Python specifically for two years or so now, so I hope I
can be forgiven.

Cheers.
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-21 Thread Terry Reedy

J Kenneth King wrote:


I was working on a program of some complexity recently and quickly
caught the issue in my tests. I knew what was going on and fixed it
expediently, but the behaviour confused me and I couldn't find any
technical documentation on it so I figured I just didn't know what it
was referred to in Python. Hence the post. :)


Language Reference / Expressions / Primaries / Calls +
Language Reference / Compound statements / Function definitions

Hmm.  Read by themselves, these are not as clear as they could be that 
what parameters get bound to are the argument objects.  One really needs 
to have read the section on assignment statements first.


--
http://mail.python.org/mailman/listinfo/python-list


function parameter scope python 2.5.2

2008-11-20 Thread J Kenneth King

I recently encountered some interesting behaviour that looks like a bug
to me, but I can't find the appropriate reference to any specifications
to clarify whether it is a bug.

Here's the example code to demonstrate the issue:

class SomeObject(object):

def __init__(self):
self.words = ['one', 'two', 'three', 'four', 'five']

def main(self):
recursive_func(self.words)
print self.words

def recursive_func(words):
if len(words)  0:
word = words.pop()
print Popped: %s % word
recursive_func(words)
else:
print Done

if __name__ == '__main__':
weird_obj = SomeObject()
weird_obj.main()


The output is:

Popped: five
Popped: four
Popped: three
Popped: two
Popped: one
Done
[]

Of course I expected that recursive_func() would receive a copy of
weird_obj.words but it appears to happily modify the object.

Of course a work around is to explicitly create a copy of the object
property befor passing it to recursive_func, but if it's used more than
once inside various parts of the class that could get messy.

Any thoughts? Am I crazy and this is supposed to be the way python works?
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-20 Thread J Kenneth King
J Kenneth King [EMAIL PROTECTED] writes:

 I recently encountered some interesting behaviour that looks like a bug
 to me, but I can't find the appropriate reference to any specifications
 to clarify whether it is a bug.

 Here's the example code to demonstrate the issue:

 class SomeObject(object):

 def __init__(self):
 self.words = ['one', 'two', 'three', 'four', 'five']

 def main(self):
 recursive_func(self.words)
 print self.words

 def recursive_func(words):
 if len(words)  0:
 word = words.pop()
 print Popped: %s % word
 recursive_func(words)
 else:
 print Done

 if __name__ == '__main__':
 weird_obj = SomeObject()
 weird_obj.main()


 The output is:

 Popped: five
 Popped: four
 Popped: three
 Popped: two
 Popped: one
 Done
 []

 Of course I expected that recursive_func() would receive a copy of
 weird_obj.words but it appears to happily modify the object.

 Of course a work around is to explicitly create a copy of the object
 property befor passing it to recursive_func, but if it's used more than
 once inside various parts of the class that could get messy.

 Any thoughts? Am I crazy and this is supposed to be the way python works?

Of course, providing a shallow (or deep as necessary) copy makes it
work, I'm curious as to why the value passed as a parameter to a
function outside the class is passed a reference rather than a copy.
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-20 Thread alex23
On Nov 21, 9:40 am, J Kenneth King [EMAIL PROTECTED] wrote:
 Of course, providing a shallow (or deep as necessary) copy makes it
 work, I'm curious as to why the value passed as a parameter to a
 function outside the class is passed a reference rather than a copy.

You're passing neither a reference nor a copy, you're passing the
object (in this case a list) directly:

http://effbot.org/zone/call-by-object.htm
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-20 Thread George Sakkis
On Nov 20, 6:40 pm, J Kenneth King [EMAIL PROTECTED] wrote:
 J Kenneth King [EMAIL PROTECTED] writes:



  I recently encountered some interesting behaviour that looks like a bug
  to me, but I can't find the appropriate reference to any specifications
  to clarify whether it is a bug.

  Here's the example code to demonstrate the issue:

  class SomeObject(object):

      def __init__(self):
          self.words = ['one', 'two', 'three', 'four', 'five']

      def main(self):
          recursive_func(self.words)
          print self.words

  def recursive_func(words):
      if len(words)  0:
          word = words.pop()
          print Popped: %s % word
          recursive_func(words)
      else:
          print Done

  if __name__ == '__main__':
      weird_obj = SomeObject()
      weird_obj.main()

  The output is:

  Popped: five
  Popped: four
  Popped: three
  Popped: two
  Popped: one
  Done
  []

  Of course I expected that recursive_func() would receive a copy of
  weird_obj.words but it appears to happily modify the object.

  Of course a work around is to explicitly create a copy of the object
  property befor passing it to recursive_func, but if it's used more than
  once inside various parts of the class that could get messy.

  Any thoughts? Am I crazy and this is supposed to be the way python works?

 Of course, providing a shallow (or deep as necessary) copy makes it
 work, I'm curious as to why the value passed as a parameter to a
 function outside the class is passed a reference rather than a copy.

Why should it be a copy by default ? In Python all copies have to be
explicit.

George
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-20 Thread Rafe
On Nov 21, 6:31 am, J Kenneth King [EMAIL PROTECTED] wrote:
 I recently encountered some interesting behaviour that looks like a bug
 to me, but I can't find the appropriate reference to any specifications
 to clarify whether it is a bug.

 Here's the example code to demonstrate the issue:

 class SomeObject(object):

     def __init__(self):
         self.words = ['one', 'two', 'three', 'four', 'five']

     def main(self):
         recursive_func(self.words)
         print self.words

 def recursive_func(words):
     if len(words)  0:
         word = words.pop()
         print Popped: %s % word
         recursive_func(words)
     else:
         print Done

 if __name__ == '__main__':
     weird_obj = SomeObject()
     weird_obj.main()

 The output is:

 Popped: five
 Popped: four
 Popped: three
 Popped: two
 Popped: one
 Done
 []

 Of course I expected that recursive_func() would receive a copy of
 weird_obj.words but it appears to happily modify the object.

 Of course a work around is to explicitly create a copy of the object
 property befor passing it to recursive_func, but if it's used more than
 once inside various parts of the class that could get messy.

 Any thoughts? Am I crazy and this is supposed to be the way python works?

You are passing a mutable object. So it can be changed. If you want a
copy, use slice:
 L = [1, 2, 3, 4, 5]
 copy = L[:]
 L.pop()
5
 L
[1, 2, 3, 4]
 copy
[1, 2, 3, 4, 5]

...in your code...

def main(self):
recursive_func(self.words[:])
print self.words

...or...

 def recursive_func(words):
 words = words[:]
 if len(words)  0:
 word = words.pop()
 print Popped: %s % word
 recursive_func(words)
 else:
 print Done

 words = [one, two, three]
 recursive_func(words)
Popped: three
Popped: two
Popped: one
Done
 words
['one', 'two', 'three']

Though I haven't been doing this long enough to know if that last
example has any drawbacks.

If we knew more about what you are trying to do, perhaps an
alternative would be even better.

- Rafe
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-20 Thread Steven D'Aprano
On Thu, 20 Nov 2008 18:31:12 -0500, J Kenneth King wrote:

 Of course I expected that recursive_func() would receive a copy of
 weird_obj.words but it appears to happily modify the object.

I am curious why you thought that. What made you think Python should/did 
make a copy of weird_obj.words when you pass it to a function?

This is a serious question, I'm not trying to trap you into something :)


-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: function parameter scope python 2.5.2

2008-11-20 Thread Arnaud Delobelle
J Kenneth King [EMAIL PROTECTED] writes:

 I recently encountered some interesting behaviour that looks like a bug
 to me, but I can't find the appropriate reference to any specifications
 to clarify whether it is a bug.

 Here's the example code to demonstrate the issue:

 class SomeObject(object):

 def __init__(self):
 self.words = ['one', 'two', 'three', 'four', 'five']

 def main(self):
 recursive_func(self.words)
 print self.words

 def recursive_func(words):
 if len(words)  0:
 word = words.pop()
 print Popped: %s % word
 recursive_func(words)
 else:
 print Done

 if __name__ == '__main__':
 weird_obj = SomeObject()
 weird_obj.main()


 The output is:

 Popped: five
 Popped: four
 Popped: three
 Popped: two
 Popped: one
 Done
 []

 Of course I expected that recursive_func() would receive a copy of
 weird_obj.words but it appears to happily modify the object.

 Of course a work around is to explicitly create a copy of the object
 property befor passing it to recursive_func, but if it's used more than
 once inside various parts of the class that could get messy.

 Any thoughts? Am I crazy and this is supposed to be the way python works?

That's because Python isn't call-by-value.  Or it is according to some,
it's just that the values it passes are references.  Which, according to
others, is unnecessarily convoluted: it's call-by-object, or shall we
call it call-by-sharing?  At least everybody agrees it's not
call-by-reference or call-by-name.

There.  I hope this helps!

-- 
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list