Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Mutability of function arguments? (http://www.velocityreviews.com/forums/t352305-mutability-of-function-arguments.html)

ex_ottoyuhr 12-08-2005 12:16 AM

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.


Carl J. Van Arsdall 12-08-2005 12:26 AM

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
cvanarsdall@mvista.com
Build and Release
MontaVista Software


Fredrik Lundh 12-08-2005 12:29 AM

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>




ex_ottoyuhr 12-08-2005 01:11 AM

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... :)


Brett g Porter 12-08-2005 01:20 AM

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 * BgPorter@acm.org


Mark Tolonen 12-08-2005 01:50 AM

Re: Mutability of function arguments?
 
"ex_ottoyuhr" <ex_ottoyuhr@hotmail.com> wrote in message
news:1134001014.716406.10800@z14g2000cwz.googlegro ups.com...
> 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



Mike Meyer 12-08-2005 01:55 AM

Re: Mutability of function arguments?
 
"ex_ottoyuhr" <ex_ottoyuhr@hotmail.com> 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/Coo.../Recipe/456150.

<mike
--
Mike Meyer <mwm@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

bonono@gmail.com 12-08-2005 02:57 AM

Re: Mutability of function arguments?
 

Mike Meyer wrote:
> "ex_ottoyuhr" <ex_ottoyuhr@hotmail.com> 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.


Mike Meyer 12-08-2005 03:37 AM

Re: Mutability of function arguments?
 
bonono@gmail.com writes:
> Mike Meyer wrote:
>> "ex_ottoyuhr" <ex_ottoyuhr@hotmail.com> 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 <mwm@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

Alex Martelli 12-08-2005 03:42 AM

Re: Mutability of function arguments?
 
Mike Meyer <mwm@mired.org> 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


All times are GMT. The time now is 03:52 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.