From: Steven D'Aprano on
On Sun, 11 Jul 2010 21:52:17 -0700, sturlamolden wrote:

> On 11 Jul, 21:37, "Alf P. Steinbach /Usenet" <alf.p.steinbach
> +use...(a)gmail.com> wrote:
>
>> Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python
>> works like Java in this respect, that's all; neither Java nor Python
>> support 'swap'.
>
> x,y = y,x


Of course that's a good alternative, but that's not what Alf, or the
original poster, are talking about.

They're specifically talking about writing a function which swaps two
variables in the enclosing scope. This is a good test of languages that
support call-by-reference, e.g. Pascal:


procedure swap(var x:integer, var y: integer):
VAR
tmp: integer;
BEGIN
tmp := x;
x := y;
y := x;
END;


If you pass two integer variables to swap(), Pascal will exchange their
values. You can't do this in Python. You can get close if you assume the
enclosing scope is global, or if you pass the name of the variables
rather than the variables themselves, but even then you can't make it
work reliably. Or at all.

Naturally the swap() function itself is not terribly useful in a language
like Python that makes exchanging variables so easy, but there are other
uses for call-by-reference that aren't quite so trivial. However, I can't
think of anything off the top of my head, so here's another trivial
example that can't work in Python:

s = "hello"
call_something_magic(s)
assert s == "goodbye"




--
Steven
From: Terry Reedy on
On 7/11/2010 1:48 PM, wheres pythonmonks wrote:

> 2. How can I write a function, "def swap(x,y):..." so that "x = 3; y
> = 7; swap(x,y);" given x=7,y=3??
> (I want to use Perl's Ref "\" operator, or C's&).
> (And if I cannot do this [other than creating an Int class], is this
> behavior limited to strings,
> tuples, and numbers)

Since you are just exploring, addendum to other answers:

>>> x,y = 1,2
>>> def swapxy():
global x,y
x,y=y,x

>>> swapxy()
>>> x,y
(2, 1)

Not too useful

>>> s = [1,2]
>>> def swap01(lis):
lis[:2] = reversed(lis[:2]) # other versions possible

>>> swap01(s)
>>> s
[2, 1]

A function can *modify* an input object. When is does, the usual
convention is that it should *not* return the object.

--
Terry Jan Reedy

From: bart.c on
"MRAB" <python(a)mrabarnett.plus.com> wrote in message
news:mailman.591.1278900548.1673.python-list(a)python.org...
> Alf P. Steinbach /Usenet wrote:

>> def foo():
>> print( blah )
>> blah = "this is both an assignment and a declaration causing it to
>> exist"
>>
>> foo()
>>
>> Clearly when the exception is raised, referring to the variable, the
>> variable exists.

> How about this:
>
> >>> def foo():
> print("Before:", locals())
> x = 0
> print("After:", locals())
>
>
> >>> foo()
> Before: {}
> After: {'x': 0}

That's interesting. So in Python, you can't tell what local variables a
function has just by looking at it's code:

def foo(day):
if day=="Tuesday":
x=0
print ("Locals:",locals())

#foo("Monday")

Does foo() have 1 or 2 locals? That might explain some of the difficulties
of getting Python implementations up to speed.

--
Bartc

From: Steven D'Aprano on
On Mon, 12 Jul 2010 09:48:04 +0100, bart.c wrote:

> That's interesting. So in Python, you can't tell what local variables a
> function has just by looking at it's code:

In the presence of "exec", you can't really tell *anything*.

>>> def f(s):
.... exec s
.... print locals()
....
>>> f("x = 2;y = None")
{'y': None, 'x': 2, 's': 'x = 2;y = None'}




> def foo(day):
> if day=="Tuesday":
> x=0
> print ("Locals:",locals())
>
> #foo("Monday")
>
> Does foo() have 1 or 2 locals?

That's easy for CPython: it prepares two slots for variables, but only
creates one:

>>> foo("Monday")
('Locals:', {'day': 'Monday'})
>>> foo.func_code.co_varnames
('day', 'x')
>>> foo.func_code.co_nlocals
2

So, the question is, is x a local variable or not? It's not in locals,
but the function clearly knows that it could be.


> That might explain some of the
> difficulties of getting Python implementations up to speed.

I'm not quite sure why you say that.


--
Steven

From: bart.c on
"Steven D'Aprano" <steve(a)REMOVE-THIS-cybersource.com.au> wrote in message
news:4c3aedd5$0$28647$c3e8da3(a)news.astraweb.com...
> On Mon, 12 Jul 2010 09:48:04 +0100, bart.c wrote:
>
>> That's interesting. So in Python, you can't tell what local variables a
>> function has just by looking at it's code:

>> def foo(day):
>> if day=="Tuesday":
>> x=0
>> print ("Locals:",locals())
>>
>> #foo("Monday")
>>
>> Does foo() have 1 or 2 locals?
>
> That's easy for CPython: it prepares two slots for variables, but only
> creates one:
>
>>>> foo("Monday")
> ('Locals:', {'day': 'Monday'})
>>>> foo.func_code.co_varnames
> ('day', 'x')
>>>> foo.func_code.co_nlocals
> 2
>
> So, the question is, is x a local variable or not? It's not in locals,
> but the function clearly knows that it could be.

So Alf P.S. could be right; x exists, but Python pretends it doesn't until
it's assigned to.

>> That might explain some of the
>> difficulties of getting Python implementations up to speed.
>
> I'm not quite sure why you say that.

Only that an implementation might be obliged to keep these various tables
updated during function execution, instead of just at entry and exit.

--
Bartc