Pass by reference

I

iu2

Hi,

Is it possible somehow to change a varible by passing it to a
function?

I tried this:

def change_var(dict0, varname, val):
dict0[varname] = val


def test():
a = 100
change_var(locals(), 'a', 3)
print a


But test() didn't work, the value a remains 100.

I have several variables initialized to None.
I need to convert each one of them an object only if it is None.
something like:

if not var1: var1 = MyObject()

I want this to be a function, that is:

def create_obj(var):
if not var: var = MyObj()
# set properties of var

Now, I know I can achieve this by functional programming,

def create_obj(var):
if not var:
x = MyObj()
# set properties of x
return x
return var

and then

var = creaet_obj(var)

Is there another way?

Thanks
 
C

Chris Rebert

Hi,

Is it possible somehow to change a varible by passing it to a
function?

I tried this:

def change_var(dict0, varname, val):
dict0[varname] = val


def test():
a = 100
change_var(locals(), 'a', 3)
print a


But test() didn't work, the value a remains 100.

Yes, that's clearly stated in the documentation for locals(); from
http://docs.python.org/library/functions.html#locals :

"Warning: The contents of this dictionary should not be modified;
changes may not affect the values of local variables used by the
interpreter."
I have several variables initialized to None.
I need to convert each one of them an object only if it is None.
something like:

if not var1: var1 = MyObject()

That should be:

if var1 is None: var1 = MyObject()

Otherwise, the "conversion" will also happen if var1 happens to be a
false but non-None object, e.g. {}, [], 0, etc
Also, it's just the idiomatic way of writing tests against None in Python.
I want this to be a function, that is:

def create_obj(var):
if not var: var = MyObj()
# set properties of var

Now, I know I can achieve this by functional programming,

def create_obj(var):
if not var:
x = MyObj()
# set properties of x
return x
return var

and then

var = creaet_obj(var)

Is there another way?

Not really, or at the very least it'll be kludgey. Python uses
call-by-object (http://effbot.org/zone/call-by-object.htm), not
call-by-value or call-by-reference.

Could you explain why you have to set so many variables to the same
value (if they're None)? It's a bit strange and could be a sign that
there's a better way to structure your program (e.g. use a
dictionary). We might be able to offer more helpful suggestions if you
explain.

Cheers,
Chris
 
B

Bruno Desthuilliers

iu2 a écrit :
Hi,

Is it possible somehow to change a varible by passing it to a
function?

For which definition of "change a variable" ?
I tried this:

def change_var(dict0, varname, val):
dict0[varname] = val

Ok, this is mutating dict0, so it works.
def test():
a = 100
change_var(locals(), 'a', 3)

Please (re)read the doc for locals():
http://www.python.org/doc/2.6/library/functions.html#locals

See the big warning ?
print a


But test() didn't work,

It did. The problem is elsewhere.
the value a remains 100.

I have several variables initialized to None.

Where ?
I need to convert each one of them an object only if it is None.
something like:

if not var1: var1 = MyObject()

Warning : some objects can eval to false in a boolean context without
being None. Better to explicitely test identity here:

if var1 is None:
var1 = Something()

I want this to be a function, that is:

def create_obj(var):
if not var: var = MyObj()

This is a rebinding, not a mutation. Here, 'var' is a local *name*, so
rebinding it will only affect the local namespace.
# set properties of var

Why don't you use the initializer of MyObj here ?

class MyObj(object):
def __init__(self, prop1, propx):
# set properties of self
self.prop1 = prop1
self.propx = propx


Then just call:

var = MyObj(somevalue, someothervalue)
Now, I know I can achieve this by functional programming,
???

def create_obj(var):
if not var:
x = MyObj()
# set properties of x
return x
return var

This is just a plain function. You may want to re-read the definition of
"functional programming" !-)
and then

var = creaet_obj(var)

Is there another way?

What's wrong with this one ?
 
I

iu2

Not really, or at the very least it'll be kludgey. Python uses
call-by-object (http://effbot.org/zone/call-by-object.htm), not
call-by-value or call-by-reference.

Could you explain why you have to set so many variables to the same
value (if they're None)? It's a bit strange and could be a sign that
there's a better way to structure your program (e.g. use a
dictionary). We might be able to offer more helpful suggestions if you
explain.

Cheers,
Chris

--

Hi, thanks for your reply.

Well, I wrote an application that talks via UDP to several targets
(embedded). Currently there are only two of them connected to my PC,
but there could be more. Let's call them target 1 and target 2.

Now, each target has its own IP address, and is connected straight to
my PC, no DHCP or common bus or whatsover
The GUI of my application enables the user to enter the IP for each
target.
The user can disconnect one target, and then connect a different one
with a different IP.
Let's say he replaces target 2 with a different one. Then he must tell
the python app that target 2 now has a different IP. He does that by
entering a different IP for target 2 in the GUI.

When the app sends data to a target, it must know whether to create a
new socket or use the previous one for that target. It deduces this by
observing a change in the IP address in the GUI for that target.

For the 2 targets I have the variables comm1 and comm2. They are of
some class I wrote, representing many properties of the communication,
including the IP address.
There is one function that sends data, and it receives a commX var
(comm1 or comm2) as the means for sending the data.
Before sending the data the function needs to initilze commX (if it is
still None), or creating it a new, if it sees that the IP for that
target has changed.

Something like this:

def send_data(comm, data, current_ip_from_gui):
if comm is None:
# I want to assign comm a new MyComm
elif comm.ip != current_ip_from_gui:
# I want to re-assign a new MyComm that uses the new IP
comm.socket.SendTo(comm.addr, data) # eventually send the data

I could re-design it to have send_data be a method of MyComm. But I
don't think I should, beacuse I planned MyComm to have only
properties. I'd like functions to receive it and manipulate it. MyComm
could also be a mere string just as well...
Since I can apply this idiom in C (pointer), Lisp (macro), tcl
(upvar) and C# (ref) I wondered what the python way was.

But I guess I can achieve this using a class holding my vars, maybe
like this:

class CommVars:
comm1 = None
comm2 = None

myvars = CommVars()

and then change a value like this:

def set_var(dict0, varname, val):
dict0[varname] = val

set_var(myvars.__dict__, 'comm1', MyComm(...))
 
A

Aaron Brady

Hi,

Is it possible somehow to change a varible by passing it to a
function?

I tried this:

def change_var(dict0, varname, val):
  dict0[varname] = val

def test():
  a = 100
  change_var(locals(), 'a', 3)
  print a

But test() didn't work, the value a remains 100.

I have several variables initialized to None.
I need to convert each one of them an object only if it is None.
something like:

if not var1: var1 = MyObject()

I want this to be a function, that is:

def create_obj(var):
  if not var: var = MyObj()
  # set properties of var

Now, I know I can achieve this by functional programming,

def create_obj(var):
  if not var:
    x = MyObj()
    # set properties of x
    return x
  return var

and then

var = creaet_obj(var)

Is there another way?

Thanks

A practical way is to use a container. Some people use lists; I like
an object.

thingref= Ref( thing )
f( thingref )
print thingref() #or thingref.get() or w'ver.

Then 'f' can assign like this:

def f( aref ):
# blah blah
aref( newthing ) #or aref.set( newthing )

But the short answer is no. A function receives the contents of a
variable, not a variable.
 
T

Terry Reedy

alex said:
I recently conquered this pass by ref thing. This is how I did it.

What you did was to pass a mutable object and mutate it. Absolutely
standard practice in Python. I am glad you learned it, but also
learning and using the standard terminology will also help. Hope you
enjoy Python too.

tjr
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top