Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #70941 > unrolled thread

Pass variable by reference

Started bySatish Muthali <satish.muthali@gmail.com>
First post2014-05-05 17:39 -0700
Last post2014-05-06 20:45 +1000
Articles 7 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Pass variable by reference Satish Muthali <satish.muthali@gmail.com> - 2014-05-05 17:39 -0700
    Re: Pass variable by reference Rustom Mody <rustompmody@gmail.com> - 2014-05-05 21:32 -0700
    Re: Pass variable by reference Steven D'Aprano <steve@pearwood.info> - 2014-05-06 08:18 +0000
      Re: Pass variable by reference Marko Rauhamaa <marko@pacujo.net> - 2014-05-06 12:11 +0300
        Re: Pass variable by reference Chris Angelico <rosuav@gmail.com> - 2014-05-06 19:53 +1000
          Re: Pass variable by reference Marko Rauhamaa <marko@pacujo.net> - 2014-05-06 13:38 +0300
            Re: Pass variable by reference Chris Angelico <rosuav@gmail.com> - 2014-05-06 20:45 +1000

#70941 — Pass variable by reference

FromSatish Muthali <satish.muthali@gmail.com>
Date2014-05-05 17:39 -0700
SubjectPass variable by reference
Message-ID<mailman.9690.1399348396.18130.python-list@python.org>

[Multipart message — attachments visible in raw view] — view raw

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

[toc] | [next] | [standalone]


#70943

FromRustom Mody <rustompmody@gmail.com>
Date2014-05-05 21:32 -0700
Message-ID<6fe61129-09d1-48eb-9877-effb7fa49d27@googlegroups.com>
In reply to#70941
On Tuesday, May 6, 2014 6:09:44 AM UTC+5:30, Satish Muthali wrote:
> 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:

>>> def foo(x,y):
...   return x+1, y+3
... 
>>> x,y= 1,2
>>> x,y=foo(x,y)
>>> x,y
(2, 5)
>>> 


> 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

[toc] | [prev] | [next] | [standalone]


#70945

FromSteven D'Aprano <steve@pearwood.info>
Date2014-05-06 08:18 +0000
Message-ID<53689aeb$0$11109$c3e8da3@news.astraweb.com>
In reply to#70941
On Mon, 05 May 2014 17:39:44 -0700, Satish Muthali wrote:

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



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#70948

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-06 12:11 +0300
Message-ID<87lhufi85o.fsf@elektro.pacujo.net>
In reply to#70945
Steven D'Aprano <steve@pearwood.info>:

> On Mon, 05 May 2014 17:39:44 -0700, Satish Muthali wrote:
>> 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

[toc] | [prev] | [next] | [standalone]


#70951

FromChris Angelico <rosuav@gmail.com>
Date2014-05-06 19:53 +1000
Message-ID<mailman.9694.1399369998.18130.python-list@python.org>
In reply to#70948
On Tue, May 6, 2014 at 7:11 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Steven D'Aprano <steve@pearwood.info>:
>
>> On Mon, 05 May 2014 17:39:44 -0700, Satish Muthali wrote:
>>> 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

[toc] | [prev] | [next] | [standalone]


#70953

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-06 13:38 +0300
Message-ID<87eh07i44p.fsf@elektro.pacujo.net>
In reply to#70951
Chris Angelico <rosuav@gmail.com>:

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

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

[toc] | [prev] | [next] | [standalone]


#70955

FromChris Angelico <rosuav@gmail.com>
Date2014-05-06 20:45 +1000
Message-ID<mailman.9696.1399373123.18130.python-list@python.org>
In reply to#70953
On Tue, May 6, 2014 at 8:38 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Chris Angelico <rosuav@gmail.com>:
>
>>>     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.
>
> 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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web