Pass variable by reference

S

Satish Muthali

Hello experts,

I have a burning question on how to pass variable by reference in Python. I understand that the data type has to be mutable.

For example, here’s the issue I am running in to:

I am trying to extract the PostgreSQL DB version for example:

pgVer = [s.split() for s in os.popen("psql --version").read().splitlines()]
print pgVer[0]
for i, var in enumerate(pgVer[0]):
if i == len(pgVer[0]) - 1:
pgversion = var

I would now like to pass ‘pgversion’ (where the value of pgversion is 9.3.4) by reference, for example:

I want to nuke /var/lib/postgresql/9.3.4/main/data , however programatically I want it to be as: /var/lib/postgresql/<value of pgversion>/main/data

Any help is appreciated.

Thanks
Satish
 
R

Rustom Mody

Hello experts,
I have a burning question on how to pass variable by reference in Python.

Technically correct answer: You cant. But see below.
I understand that the data type has to be mutable.

I dont know that mutability has any bearing on this


You can get mostly the effect of pass by reference by using:
- multiple values (tuple) return
- unpacking assignment

Like so:
.... return x+1, y+3
....
For example, here's the issue I am running in to:
I am trying to extract the PostgreSQL DB version for example:
pgVer = [s.split() for s in os.popen("psql --version").read().splitlines()]
print pgVer[0]
for i, var in enumerate(pgVer[0]):
if i == len(pgVer[0]) - 1:
pgversion = var
I would now like to pass 'pgversion' (where the value of pgversion is 9.3.4) by reference, for example:
I want to nuke /var/lib/postgresql/9.3.4/main/data , however programatically I want it to be as: /var/lib/postgresql/<value of pgversion>/main/data

I dont really understand your example
 
S

Steven D'Aprano

Hello experts,

I have a burning question on how to pass variable by reference in
Python. I understand that the data type has to be mutable.

Python provides neither pass-by-reference nor pass-by-value argument
passing. Please read this for an explanation of why people sometimes
think that it does, and what Python actually does instead:

http://import-that.dreamwidth.org/1130.html


To get an effect *similar* to pass-by-reference, you can wrap your
variable in a list, and then only operate on the list item. For example:


one = [1]
two = [2]

def swap(a, b):
a[0], b[0] = b[0], a[0]

swap(one, two)
print one[0], two[0]
=> will print "2 1"


But note carefully that in the swap function I do not assign directly to
the arguments a and b, only to their items a[0] and b[0]. If you assign
directly to a and b, you change the local variables.

# This does not work.
def swap(a, b):
a, b = b, a


Rather than trying to fake pass-by-reference semantics, it is much better
to understand Python's capabilities and learn how to use it to get the
same effect. For example, instead of writing a swap procedure, it is much
simpler to just do this:

one = 1
two = 2
one, two = two, one
print one, two
=> will print "2 1"
For example, here’s the issue I am running in to:

I am trying to extract the PostgreSQL DB version for example:

pgVer = [s.split() for s in os.popen("psql
--version").read().splitlines()]
print pgVer[0]
for i, var in enumerate(pgVer[0]):
if i == len(pgVer[0]) - 1:
pgversion = var

I would now like to pass ‘pgversion’ (where the value of pgversion is
9.3.4) by reference, for example:

I want to nuke /var/lib/postgresql/9.3.4/main/data , however
programatically I want it to be as: /var/lib/postgresql/<value of
pgversion>/main/data

I don't understand this. I think you mean that you want to delete a file,
but you don't know the pathname of the file until you have extracted the
version number as a string.

path = "/var/lib/postgresql/%s/main/data"
os.unlink(path % pgversion)

will probably do what you want. Pass-by-reference doesn't come into this.

If this is not what you mean, please explain in more detail.
 
M

Marko Rauhamaa

Steven D'Aprano said:
I have a burning question on how to pass variable by reference in
Python. I understand that the data type has to be mutable.

[...]

To get an effect *similar* to pass-by-reference, you can wrap your
variable in a list, and then only operate on the list item.

Consider also returning multiple values in a tuple.

In C:

stats_read(stats, &characters, &words, &lines);

In Python:

characters, words, lines = stats.read()


Marko
 
C

Chris Angelico

Steven D'Aprano said:
I have a burning question on how to pass variable by reference in
Python. I understand that the data type has to be mutable.

[...]

To get an effect *similar* to pass-by-reference, you can wrap your
variable in a list, and then only operate on the list item.

Consider also returning multiple values in a tuple.

In C:

stats_read(stats, &characters, &words, &lines);

In Python:

characters, words, lines = stats.read()

That's not really pass-by-reference, though. What you're doing is
output parameters, which are usually implemented in C with pointers,
but in Python with a return tuple. Pass-by-reference allows the callee
to see and modify something in the caller's environment; for instance,
the stats_read() C function might maintain stats in the three
pointed-to integers, eg incrementing them for each char/word/line
processed. The Python equivalent would need to pass them as parameters
AND return them. For that sort of case, you'd probably want to pass an
object with three attributes (or maybe a dict or a list), which would
then be modified; that's a much closer approximation of
pass-by-reference. Hence Steven's statement about wrapping it in a
list.

And, by the way, it's not purely academic. There have been times when
I've done exactly that as a means of passing state around. It's not
common, but it has its place.

ChrisA
 
M

Marko Rauhamaa

Chris Angelico said:
That's not really pass-by-reference, though. What you're doing is
output parameters, which are usually implemented in C with pointers,
but in Python with a return tuple.

Correct, but it is worth questioning the question itself: what do you
need pass-by-reference for? A very common case is returning multiple
values. For that, Python has other idioms available.
And, by the way, it's not purely academic. There have been times when
I've done exactly that as a means of passing state around. It's not
common, but it has its place.

Nobody has been disputing Steven's technique. There are many variations
to that as well. For example, instead of a list, there might be an
appropriate class/object that could host the interesting piece of
information and act as the desired reference.


Marko
 
C

Chris Angelico

Correct, but it is worth questioning the question itself: what do you
need pass-by-reference for? A very common case is returning multiple
values. For that, Python has other idioms available.

Oh, absolutely. As in many other cases, you shouldn't ask "How do I do
<some non-Python idiom> in Python", but should ask "How do I
accomplish <some goal> in Python". Only in a few cases is the first
question reasonable (eg "How do I call this function from Python",
naming some function from a C library), and even then, it's
semantically arguable.

ChrisA
 

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

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top