Re: Mutability of function arguments?
ex_ottoyuhr wrote: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). This is already what you have. In Python, all you have are references to objects, there is no local version. I've looked around on this newsgroup and elsewhere, and I gather that this is a very common concern in Python, but one which is ordinarily answered with No, you can't. Neat, huh? Pardon ??? def appendToList(aList, aValue): ... aList.append(aValue) ... mylist = range(10) mylist [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] appendToList(mylist, 42) mylist [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 42] Now the usual considerations apply : - rebinding an arg has of course only local effect - immutable objects are still immutables Also note that since 1/ Python as a good support for exception handling 2/ a function can return multiple values [1], there is less need for such constructs than in C or C++. [1] the truth is that the function can return a unique tuple, that can be unpacked as any other. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
Mike Meyer wrote: ex_ottoyuhr [EMAIL PROTECTED] writes: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). C++'s '' causes an argument to be passed by reference. Python does that with all arguments. Any changes you make to the argument in the function will be seen in the caller unless you explicitly make a copy to pass. I would say, from the point of view of a C++ programmer, Python passes references by value. In other words if you think of variables as pointers (references) to values, and function call as passing the reference by value, the behaviour of Python makes sense. Kent -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
Kent Johnson [EMAIL PROTECTED] writes: Mike Meyer wrote: ex_ottoyuhr [EMAIL PROTECTED] writes: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). C++'s '' causes an argument to be passed by reference. Python does that with all arguments. Any changes you make to the argument in the function will be seen in the caller unless you explicitly make a copy to pass. I would say, from the point of view of a C++ programmer, Python passes references by value. In other words if you think of variables as pointers (references) to values, and function call as passing the reference by value, the behaviour of Python makes sense. While the description is right, the terminology is wrong, and places the emphasis in the wrong place. Your description of passes references by value is a description of call by reference. C passes all arguments by value, to pass a reference, the C programmer creates the reference to the value by hand, then dereferences it by hand at the other end. So C's call-by-reference passes the reference by value. There's no difference between C's call-by-reference and Python's call-by-reference, and using different words to try and imply there is will just cause problems further on. The real difference is in the way names behave in the two languages. As you put it, variables are references to values, except Python names don't have most of the things associated with variables in other programming languages, so it's better to call them names. We use bound to show that we're not copying a value over a fixed memory location, hence names are bound to values. This is the crucial point, and the one that need to be emphasized. mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
Mike Meyer wrote: Your description of passes references by value is a description of call by reference. C passes all arguments by value, to pass a reference, the C programmer creates the reference to the value by hand, then dereferences it by hand at the other end. So C's call-by-reference passes the reference by value. There's no difference between C's call-by-reference and Python's call-by-reference, and using different words to try and imply there is will just cause problems further on. can you guys please stop using call by value and call by reference when you discuss Python. both terms have established meanings, and Python's argument passing model doesn't match any of them. this was known some 30 years ago; here's a quote from a CLU reference manaual from 1979: We call the argument passing technique _call by sharing_, because the argument objects are shared between the caller and the called routine. This technique does not correspond to most traditional argument passing techniques (it is similar to argument passing in LISP). In particular IT IS NOT call by value because mutations of arguments per- formed by the called routine will be visible to the caller. And IT IS NOT call by reference because access is not given to the variables of the caller, but merely to certain objects. (CLU was one of the first languages to use objects in the Python sense, as well as the same argument passing model as today's Python) established terms for Python's argument passing model are call by object or call by sharing for more on this, see the comp.lang.python archives. /F -- http://mail.python.org/mailman/listinfo/python-list
Mutability of function arguments?
I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). I've looked around on this newsgroup and elsewhere, and I gather that this is a very common concern in Python, but one which is ordinarily answered with No, you can't. Neat, huh? A few websites, newsgroup posts, etc. have recommended that one ask for a more Pythonic way of doing things; so, is there one, or at least one that doesn't involve using objects as wrappers for mutable arguments? And, indeed, would that approach work? Would declaring: class FooWrapper : __init__(fooToLoad) : self.foo = fooToLoad mean that I could now declare a FooWrapper holding a foo, pass the FooWrapper to a function, and have the function conclude with the foo within the FooWrapper now modified? Thanks in advance for everyone's time; I hope I'm comprehensible. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
(Re. mutability question:) Update, never mind. I found that the FooWrapper solution isn't so bad after all -- and even better is putting the variable in question in a different module entirely. However, anyone who wants to answer the question is still welcome to. Sorry to be a bother, and to have posted before I thought... :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
ex_ottoyuhr [EMAIL PROTECTED] writes: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). C++'s '' causes an argument to be passed by reference. Python does that with all arguments. Any changes you make to the argument in the function will be seen in the caller unless you explicitly make a copy to pass. I've looked around on this newsgroup and elsewhere, and I gather that this is a very common concern in Python, but one which is ordinarily answered with No, you can't. Neat, huh? A few websites, newsgroup posts, etc. have recommended that one ask for a more Pythonic way of doing things; so, is there one, or at least one that doesn't involve using objects as wrappers for mutable arguments? If your arguments are mutable, you don't need to do anything to be able to change them - just call the mutator methods. If your arguments aren't mutable, then you can't change them, either in the function or in the original namespace. If what you really want to do is rebind a variable in the calling namespace - well, you can't do that. The standard way to deal with the usual uses for passing references in C is to return the value (or values - Python handles multi-valued return and assignment much cleaner than C++) and rebind the variables at the point of the call. If you insist on writing C/C++ in Python, you can wrap an immutable object in an instance of class with a method to let you change it, as you suggest: And, indeed, would that approach work? Would declaring: class FooWrapper : __init__(fooToLoad) : self.foo = fooToLoad mean that I could now declare a FooWrapper holding a foo, pass the FooWrapper to a function, and have the function conclude with the foo within the FooWrapper now modified? If you like an extended lambda calculus syntax, you can use my Ref class: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456150. mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
ex_ottoyuhr [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). I've looked around on this newsgroup and elsewhere, and I gather that this is a very common concern in Python, but one which is ordinarily answered with No, you can't. Neat, huh? A few websites, newsgroup posts, etc. have recommended that one ask for a more Pythonic way of doing things; so, is there one, or at least one that doesn't involve using objects as wrappers for mutable arguments? And, indeed, would that approach work? Would declaring: class FooWrapper : __init__(fooToLoad) : self.foo = fooToLoad mean that I could now declare a FooWrapper holding a foo, pass the FooWrapper to a function, and have the function conclude with the foo within the FooWrapper now modified? Thanks in advance for everyone's time; I hope I'm comprehensible. Python isn't C++ and there is no need to return multiple values by modifying function parameters: def funct(a,b): ... return a+1,b+1 ... foo,bar=1,2 print foo,bar 2 3 foo,bar=funct(foo,bar) print foo,bar 3 4 -Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
Mike Meyer wrote: ex_ottoyuhr [EMAIL PROTECTED] writes: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). C++'s '' causes an argument to be passed by reference. Python does that with all arguments. Any changes you make to the argument in the function will be seen in the caller unless you explicitly make a copy to pass. except when foo and bar are bound to immutable objects. In C: int foo=1; int bar=2; void update(int *a, int *b) { *a=3; *b=4} update(foo, bar); In Python: foo=1 bar=2 def update(a,b): a=3; b=4 update(foo,bar) Many people from C/C++ background would be tricked for this situation. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
ex_ottoyuhr wrote: I've looked around on this newsgroup and elsewhere, and I gather that this is a very common concern in Python, but one which is ordinarily answered with No, you can't. Neat, huh? A few websites, newsgroup posts, etc. have recommended that one ask for a more Pythonic way of doing things; so, is there one, or at least one that doesn't involve using objects as wrappers for mutable arguments? anyone that holds a reference to a mutable object can modify it, and everyone that has the same reference will see the changes. assignment copies references, not values: foo = [] value = foo foo.append(hello) foo.append(world) value ['hello', 'world'] And, indeed, would that approach work? Would declaring: class FooWrapper : __init__(fooToLoad) : self.foo = fooToLoad mean that I could now declare a FooWrapper holding a foo, pass the FooWrapper to a function, and have the function conclude with the foo within the FooWrapper now modified? if self.foo is a mutable object, and your function is modifying it in place, yes: class FooWrapper: ... def __init__(self, fooToLoad): ... self.foo = fooToLoad ... value = [] foo = FooWrapper(value) foo.foo [] value [] def mutator(x): ... x.foo.append(hello) ... mutator(foo) mutator(foo) foo.foo ['hello', 'hello'] value ['hello', 'hello'] however, if the mutator replaces the wrapped object, the original object will not see the changes. you can still see them via the wrapper, of course: def mutator(x): ... x.foo = [goodbye] ... mutator(foo) foo.foo ['goodbye'] value ['hello', 'hello'] this might help: http://effbot.org/zone/python-objects.htm /F -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
ex_ottoyuhr wrote: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). I've looked around on this newsgroup and elsewhere, and I gather that this is a very common concern in Python, but one which is ordinarily answered with No, you can't. Neat, huh? A few websites, newsgroup posts, etc. have recommended that one ask for a more Pythonic way of doing things; so, is there one, or at least one that doesn't involve using objects as wrappers for mutable arguments? And, indeed, would that approach work? Would declaring: class FooWrapper : __init__(fooToLoad) : self.foo = fooToLoad mean that I could now declare a FooWrapper holding a foo, pass the FooWrapper to a function, and have the function conclude with the foo within the FooWrapper now modified? Well, you can test it yourself: class wrapper(object): ...def __init__(self, val): ... self.val = val ... w = wrapper(42) w.val 42 def foo(w): ...w.val = 11 ... foo(w) w.val 11 Thanks in advance for everyone's time; I hope I'm comprehensible. You're comprehensible, but I think that you're also thinking in C++. The object model that Python follows is very different -- instead of thinking of assignment meaning Stick this value into this named location, you need to switch to thinking of assignment as meaning stick this name onto that object until I tell you otherwise. If you're trying to return multiple values from a function, Python lets you do that def multiFoo(x, y, z): ...return x*2, y*2, z*2 ... x = 1 y = 2 z = 3 x, y, z = multiFoo(x, y, z) x 2 y 4 z 6 -- // Today's Oblique Strategy (© Brian Eno/Peter Schmidt): // Repetition is a form of change // Brett g Porter * [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
[EMAIL PROTECTED] writes: Mike Meyer wrote: ex_ottoyuhr [EMAIL PROTECTED] writes: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). C++'s '' causes an argument to be passed by reference. Python does that with all arguments. Any changes you make to the argument in the function will be seen in the caller unless you explicitly make a copy to pass. except when foo and bar are bound to immutable objects. Wrong. In C: int foo=1; int bar=2; void update(int *a, int *b) { *a=3; *b=4} update(foo, bar); Note that this update is using an assignment statement, and thus changing the arguments. In Python: foo=1 bar=2 def update(a,b): a=3; b=4 update(foo,bar) This update isn't changing the objects, it's rebinding the names in the local name space. Since you didn't change the objects, there's no change to see in the calling environment. Many people from C/C++ background would be tricked for this situation. That's because they don't understand binding. Any language that has bindings instead of has assignments will trick them this way. mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
Mike Meyer [EMAIL PROTECTED] wrote: Many people from C/C++ background would be tricked for this situation. That's because they don't understand binding. Any language that has bindings instead of has assignments will trick them this way. ...Java being probably the most popular example... Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
And, indeed, would that approach work? Would declaring: class FooWrapper : __init__(fooToLoad) : self.foo = fooToLoad mean that I could now declare a FooWrapper holding a foo, pass the FooWrapper to a function, and have the function conclude with the foo within the FooWrapper now modified? Yes, passing FooWrapper will pass by reference to a python function thereby allowing you to edit the fooToLoad HTH, carl -- Carl J. Van Arsdall [EMAIL PROTECTED] Build and Release MontaVista Software -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
Mike Meyer wrote: [EMAIL PROTECTED] writes: Mike Meyer wrote: ex_ottoyuhr [EMAIL PROTECTED] writes: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). C++'s '' causes an argument to be passed by reference. Python does that with all arguments. Any changes you make to the argument in the function will be seen in the caller unless you explicitly make a copy to pass. except when foo and bar are bound to immutable objects. Wrong. In C: int foo=1; int bar=2; void update(int *a, int *b) { *a=3; *b=4} update(foo, bar); Note that this update is using an assignment statement, and thus changing the arguments. void update(int a, int b) { a=3; b=4} Is this also an assignment statement ? In Python: foo=1 bar=2 def update(a,b): a=3; b=4 update(foo,bar) This update isn't changing the objects, it's rebinding the names in the local name space. Since you didn't change the objects, there's no change to see in the calling environment. Many people from C/C++ background would be tricked for this situation. That's because they don't understand binding. Any language that has bindings instead of has assignments will trick them this way. Sure, any language that behave like this would trick them, I am not saying python is the only one or that there is anything wrong with this behaviour. I was just saying that it is a situation that they get tricked, because of their perception about =, especially when they are told that any change to the arguments are seen by the caller. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
[EMAIL PROTECTED] writes: Mike Meyer wrote: [EMAIL PROTECTED] writes: Mike Meyer wrote: ex_ottoyuhr [EMAIL PROTECTED] writes: I'm trying to create a function that can take arguments, say, foo and bar, and modify the original copies of foo and bar as well as its local versions -- the equivalent of C++ funct(foo, bar). C++'s '' causes an argument to be passed by reference. Python does that with all arguments. Any changes you make to the argument in the function will be seen in the caller unless you explicitly make a copy to pass. except when foo and bar are bound to immutable objects. Wrong. In C: int foo=1; int bar=2; void update(int *a, int *b) { *a=3; *b=4} update(foo, bar); Note that this update is using an assignment statement, and thus changing the arguments. void update(int a, int b) { a=3; b=4} Is this also an assignment statement ? Yes. But C calls by value, and passes copies of the original a and b in. So in this case, you change the copies. In Python: foo=1 bar=2 def update(a,b): a=3; b=4 update(foo,bar) This update isn't changing the objects, it's rebinding the names in the local name space. Since you didn't change the objects, there's no change to see in the calling environment. Many people from C/C++ background would be tricked for this situation. That's because they don't understand binding. Any language that has bindings instead of has assignments will trick them this way. Sure, any language that behave like this would trick them, I am not saying python is the only one or that there is anything wrong with this behaviour. I was just saying that it is a situation that they get tricked, because of their perception about =, especially when they are told that any change to the arguments are seen by the caller. Except trick is a poor word choice. Nobody is playing a trick on them - they just don't understand what is going on. mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
Mike Meyer wrote: Except trick is a poor word choice. Nobody is playing a trick on them - they just don't understand what is going on. oops, never thought about the negative meaning of it, it is just meant as not behave as expected, what would be the word you use then ? -- http://mail.python.org/mailman/listinfo/python-list
Re: Mutability of function arguments?
[EMAIL PROTECTED] writes: Except trick is a poor word choice. Nobody is playing a trick on them - they just don't understand what is going on. oops, never thought about the negative meaning of it, it is just meant as not behave as expected, what would be the word you use then ? Surprise? mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list