IsString

S

Steven D'Aprano

I don't know if I can help with this much, I'm still somewhat new to
python, but it is my understanding that "simple" variable, ei, strings,
ints, etc, although they don't have such names, behave like variables,
ei, if you pass them to a function, the function will copy them into a
new spot.

No. You can test this yourself:

s = "This is a BIG 'simple' variable." * (10 * 1024**2)
# s will take up at least 320 megabytes of memory

Watch how long it takes to create that big string -- on my (reasonably
fast) PC, there is a noticeable pause of five seconds the first time I
do it, and a longer pause of fifteen seconds the second time, with
noticeable disk-activity.

Pass s to a function, and see if there is a similar pause.

Python NEVER duplicates objects unless you explicitly ask it to, e.g. with
the copy module, or by using slicing s[:].

However, if you use lists, then it only passes a pointer, or
tuples as well. Ei, I just ran this through the python IDE.

Test

This seems to indicate that the variable is copied, as the value didn't
change.

Seems to, but no.

Python does not use a call by value ("arguments are copied when you pass
them to a function") model, nor does it use a call by reference
("pointers to arguments are passed to functions") model, except maybe
internally in the underlying C implementation. If you think about Python
as if it were C or Java, you will forever be confused about its behaviour.
Understand Python's call by object behaviour, and it will all make sense.
Other than this, I basically see a fight on terminology, and that's
that.

Terminology is important, because we understand the world through
language. If your language is confused or misleading, your understanding
will also be confused or incomplete.
 
C

Chris Mellon

Terminology is important, because we understand the world through
language. If your language is confused or misleading, your understanding
will also be confused or incomplete.

I think the issue is pretty simple, myself:

With mutable objects, Python has the semantics normally associated
with pass-by-reference.

With immutable objects, Python has the semantics normally associated
with pass-by-value.

So you could say that Python has both pass-by reference and
pass-by-value (modulo the fact that pass-by-reference doesn't exist at
some level, and is a semantic layer on top of pass-by-value. But
semantics are what we're talking about here).

However, there is *no way* in Python to get pass-by-value semantics
with a mutable object, or pass-by-reference semantics with an
immutable one (you can build your own scaffolding to mimic it, but the
language won't change it's semantics for you).

Therefore, it's more correct to say that Python has neither
pass-by-reference semantics or pass-by-value semantics, but some third
thing. And thus the name pass-by-object, where the calling semantics
are that you always get a reference to an object, but what (if any)
other names are bound to that object, or if they can be bound to that
object, depends on the object.

When you can pass a mutable int to a function (not pass a
namespace/name pair, but a real live mutable int), then Python will
have pass-by-reference.

When you can pass a list that isn't a shared reference without
explicitly copying it or subclassing it to be immutable, then Python
will have pass-by-value.

In the meantime, it has pass-by-object.
 
C

Chris Mellon

I think the issue is pretty simple, myself:

With mutable objects, Python has the semantics normally associated
with pass-by-reference.

With immutable objects, Python has the semantics normally associated
with pass-by-value.


Meant to include this in first post:

This is all you have to know to use Python, even very advanced Python.
Everything after this point is basically comp-sci trivia and argument
about definitions.
So you could say that Python has both pass-by reference and
pass-by-value (modulo the fact that pass-by-reference doesn't exist at
some level, and is a semantic layer on top of pass-by-value. But
semantics are what we're talking about here).

However, there is *no way* in Python to get pass-by-value semantics
with a mutable object, or pass-by-reference semantics with an
immutable one (you can build your own scaffolding to mimic it, but the
language won't change it's semantics for you).

Therefore, it's more correct to say that Python has neither
pass-by-reference semantics or pass-by-value semantics, but some third
thing. And thus the name pass-by-object, where the calling semantics
are that you always get a reference to an object, but what (if any)
other names are bound to that object, or if they can be bound to that
object, depends on the object.

When you can pass a mutable int to a function (not pass a
namespace/name pair, but a real live mutable int), then Python will
have pass-by-reference.

When you can pass a list that isn't a shared reference without
explicitly copying it or subclassing it to be immutable, then Python
will have pass-by-value.

In the meantime, it has pass-by-object.
 
M

Mike Meyer

Chris Mellon said:
I think the issue is pretty simple, myself:
With mutable objects, Python has the semantics normally associated
with pass-by-reference.

Except when it doesn't. For instance, if that were true, then in this:
.... x = x + [1]
....

y would be [1] at the end, not []. The value of x is correct.
With immutable objects, Python has the semantics normally associated
with pass-by-value.

When you pass a reference to an immutable object, call-by-value and
call-by-reference have the same semantics. Unless you include object
identity as part of the semantics, in which case Python has
call-by-reference semantics and not call-by-value semantics.
However, there is *no way* in Python to get pass-by-value semantics
with a mutable object, or pass-by-reference semantics with an
immutable one (you can build your own scaffolding to mimic it, but the
language won't change it's semantics for you).

You do call-by-value in Python the same way you do call-by-reference
in C: you create the appropriate object to pass by hand. And the
semantics of Python argument handling with immutable objects are
closer to call-by-reference than they are to call-by-value.

Mutable/immutable is a red herring, caused because the solution to
wanting to change an immutable object in a function is to pass a
mutable object that refers to the immutable object.
Therefore, it's more correct to say that Python has neither
pass-by-reference semantics or pass-by-value semantics, but some third
thing.

Except that both your points are wrong, casting *serious* doubt on
your conclusion.
And thus the name pass-by-object, where the calling semantics are
that you always get a reference to an object,

"You always get a reference to an object"? That sure sounds like
call-by-refence to me. And in fact, every object that Python can
generate will have call-by-reference semantics when passed as an
argument.

The thing is, a common use for call-by-reference is to pass a
reference to a variable. Python doesn't have variables, it has
names. You can't generate a reference to a name (which is one of the
reasons we call them names instead of variables). That meas that you
can't use that idiom in python.
but what (if any) other names are bound to that object, or if they
can be bound to that object, depends on the object.

I have no idea what you're trying to say here, but in general what
names are bound to an don't depend on the object at all.

<mike
 
D

Donn Cave

Quoth Chris Mellon <[email protected]>:
| <snip a bunch of stuff>
|> Terminology is important, because we understand the world through
|> language. If your language is confused or misleading, your understanding
|> will also be confused or incomplete.
|
| I think the issue is pretty simple, myself:
|
| With mutable objects, Python has the semantics normally associated
| with pass-by-reference.
|
| With immutable objects, Python has the semantics normally associated
| with pass-by-value.

That's simple? Where most of us understand it to work in one consistent
way, you need two ways?

Look, whatever you call the passing mechanism, there is _no_ difference
that depends on whether the object is mutable. We can leave the definition
of mutable up to you, because it doesn't make any difference in this case
what it is. Whatever properties an object may have when passed, the same
object arrives as a parameter with its properties unchanged, so obviously
the same semantics obtain.

Moreover, thinking about anything in terms of mutability is worse than a
waste of time, outside of a few odd cases like dictionary keys.

Donn Cave, (e-mail address removed)
 
S

Steve Holden

Steven said:
Would you have a problem with me describing Python as an untyped
high-level assembly-language, and then working around the lack of JMP
using try...exempt?

Of course, I understand that it is no skin off your nose whether I write
bad code or not, but you might get mighty frustrated with my constant
questions on the news group "How do I write this piece of assembly code in
Python?".
I was merely trying to imply that this particular piece of
interpreter-navel-gazing has gone on way too long to sustain most
readers' interest.

regards
Steve
 
A

Alex Martelli

Steven D'Aprano said:
If you think about Python
as if it were C or Java, you will forever be confused about its behaviour.

Thinking of it as Java actually works great here.
Understand Python's call by object behaviour, and it will all make sense.

Java's behavior is identical, excepting only Java's "primitives" (e.g.
floats), but definitely identical e.g. for strings (also immutable) and
class instances (normally mutable).


Alex
 

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,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top