472,146 Members | 1,382 Online

# IsString

I need a function that will tell if a given variable is a character or
a number. Is there a way to do this? Thanks!

Dec 12 '05 #1
46 11279
"Tuvas" <tu*****@gmail.com> wrote in
I need a function that will tell if a given variable is a
character or a number. Is there a way to do this? Thanks!

If you really need to, you can test for type:
for x in ['3',3,3.1,3j]: .... print type(x)

<type 'str'>
<type 'int'>
<type 'float'>
<type 'complex'> for x in ['3',3,3.1,3j]:

.... if type(x) is str: print "it's a string"
.... elif type(x) is int: print "it's an int"
.... elif type(x) is float: print "it's a float"
.... elif type(x) is complex: print "it's a complex number"

it's a string
it's an int
it's a float
it's a complex number

--
rzed
Dec 12 '05 #2
Tuvas wrote:
I need a function that will tell if a given variable is a character or
a number. Is there a way to do this? Thanks!

You can test the type of the object as follows:
a='abc'
isinstance(a, str) True isinstance(a, (list, tuple)) False

The old way was to use type(a), but I think isinstance is
the new "preferred" method.

Larry Bates
Dec 12 '05 #3
On 12 Dec 2005 08:26:06 -0800, Tuvas <tu*****@gmail.com> wrote:
I need a function that will tell if a given variable is a character or
a number. Is there a way to do this? Thanks!

Use isinstance().

e.g.:

x = 7
isinstance(x, int)
-> True
isinstance(x, basestring)
-> False
x = "Hello"
isinstance(x, int)
-> False
isinstance(x, basestring)
-> True

I always use the basestring class for comparison, unless I need to
know whether or not the string is unicode.

--

# p.d.
Dec 12 '05 #4
Tuvas wrote:
I need a function that will tell if a given variable is a character or
a number. Is there a way to do this? Thanks!

What's your use case? This need is incommon in Python...

STeVe
Dec 12 '05 #5
On Mon, 12 Dec 2005 14:24:48 -0700, Steven Bethard wrote:
Tuvas wrote:
I need a function that will tell if a given variable is a character or
a number. Is there a way to do this? Thanks!

What's your use case? This need is incommon in Python...

No offense to the four or five helpful folks who answered Tuvas with
explanations of type() and isinstance(), but there is such a thing as dumb
insolence. I should know, I've done it often enough: answer the question

Satisfying, isn't it? *wink*

Judging by the tone of the original poster's question, I'd say for sure he
is an utter Python newbie, probably a newbie in programming in general,
so I bet that what (s)he really wants is something like this:

somefunction("6")
-> It is a number.

somefunction("x")
-> It is a character.
So, at the risk of completely underestimating Tuvas' level of programming
sophistication, I'm going to answer the question I think he meant to ask:
how do I tell the difference between a digit and a non-digit?

import string
def isDigit(s):
if len(s) != 1:
# a digit must be a single character, anything more
# or less can't be a digit
return False
else:
return s in string.digits
If you know that you are only dealing with a single character c, never a
longer string, you can just use the test:

c in string.digits
--
Steven.

Dec 12 '05 #6
Steven D'Aprano wrote:
Judging by the tone of the original poster's question, I'd say for sure he
is an utter Python newbie, probably a newbie in programming in general,
so I bet that what (s)he really wants is something like this:

somefunction("6")
-> It is a number.

somefunction("x")
-> It is a character.

So, at the risk of completely underestimating Tuvas' level of programming
sophistication, I'm going to answer the question I think he meant to ask:
how do I tell the difference between a digit and a non-digit?

import string
def isDigit(s):
if len(s) != 1:
# a digit must be a single character, anything more
# or less can't be a digit
return False
else:
return s in string.digits
If you know that you are only dealing with a single character c, never a
longer string, you can just use the test:

c in string.digits

Or better yet, use str.isdigit:

py> '6'.isdigit()
True
py> 'x'.isdigit()
False
py> def is_single_digit(s):
.... return len(s) == 1 and s.isdigit()
....
py> is_single_digit('6')
True
py> is_single_digit('66')
False

STeVe
Dec 13 '05 #7
Steven D'Aprano wrote:
On Mon, 12 Dec 2005 14:24:48 -0700, Steven Bethard wrote:

Tuvas wrote:
I need a function that will tell if a given variable is a character or
a number. Is there a way to do this? Thanks!

What's your use case? This need is incommon in Python...

No offense to the four or five helpful folks who answered Tuvas with
explanations of type() and isinstance(), but there is such a thing as dumb
insolence. I should know, I've done it often enough: answer the question

Satisfying, isn't it? *wink*

Judging by the tone of the original poster's question, I'd say for sure he
is an utter Python newbie, probably a newbie in programming in general,
so I bet that what (s)he really wants is something like this:

somefunction("6")
-> It is a number.

somefunction("x")
-> It is a character.
So, at the risk of completely underestimating Tuvas' level of programming
sophistication, I'm going to answer the question I think he meant to ask:
how do I tell the difference between a digit and a non-digit?

import string
def isDigit(s):
if len(s) != 1:
# a digit must be a single character, anything more
# or less can't be a digit
return False
else:
return s in string.digits
If you know that you are only dealing with a single character c, never a
longer string, you can just use the test:

c in string.digits

variable is a character or a number". I figured that even if he
is coming from another language he knows the difference between
"a given variable" and the "contents of a give variable". I guess
we will see.... ;-). This list is so good, he gets BOTH questions

-Larry Bates
Dec 13 '05 #8
On Mon, 12 Dec 2005 18:51:36 -0600, Larry Bates wrote:

[snippidy-doo-dah]
variable is a character or a number". I figured that even if he
is coming from another language he knows the difference between
"a given variable" and the "contents of a give variable". I guess
we will see.... ;-). This list is so good, he gets BOTH questions

The problem is, Python doesn't have variables (although it is
oh-so-tempting to use the word, I sometimes do myself). It has names in
namespaces, and objects.

It be a subtle difference, but an important one. That's why, for instance,
Python is neither call by reference nor call by value, it is call by
object.

--
Steven.

Dec 13 '05 #9
Tuvas wrote:
I need a function that will tell if a given variable is a character or
a number. Is there a way to do this? Thanks!

In Python, all values have an associated type which you can query with
type(v) thus:

from types import *

if type(v) == IntType:
... whatever ...

Several types would qualify as "numbers": IntType, FloatType, LongType,
and ComplexType,
and several as "strings": StringType and UnicodeType

Gary Herron

Dec 13 '05 #10
Gary Herron wrote:
In Python, all values have an associated type which you can query with
type(v) thus:

from types import *

if type(v) == IntType:
... whatever ...

Several types would qualify as "numbers": IntType, FloatType, LongType,
and ComplexType,
and several as "strings": StringType and UnicodeType

This is bad practice on so many levels...

If you really do need to test for a type use isinstance, not
'type(v)==something'.

You didn't need to import any of those types from types: they are all
builtins albeit under different names.

If you really must:

if isinstance(v, (int, float, long, complex)):
...

or for strings use the base type:

if isinstance(v, basestring):
...
Dec 13 '05 #11
LOL. As to me being a newbie to programming, well, I've been
programming to some extent for the last 10 years, although never
professionally. The first few questions were enough to help me solve
the problem that I had. And I've been programming Python for 4 months
or so, but it's been pretty intense, my current code is about 1000
lines or so for the program that I am doing. The reason I had this need
is basically trying to correct a mistake that I had made, sometime I
passed a function characters, other times I passed it numbers, and I
needed to have one uniform system. But, after a while, I found that I
really didn't need this uniformed system, so I was alright. But, thanks
for all of our help!

Dec 13 '05 #12
On Tue, 13 Dec 2005, Steven D'Aprano wrote:
On Mon, 12 Dec 2005 18:51:36 -0600, Larry Bates wrote:

[snippidy-doo-dah]
variable is a character or a number". I figured that even if he is
coming from another language he knows the difference between "a given
variable" and the "contents of a give variable". I guess we will
see.... ;-). This list is so good, he gets BOTH questions answered.
The problem is, Python doesn't have variables (although it is
oh-so-tempting to use the word, I sometimes do myself). It has names in
namespaces, and objects.

In what sense are the names-bound-to-references-to-objects not variables?
It be a subtle difference, but an important one.
No, it's just spin, bizarre spin for which i can see no reason. Python has
variables.
That's why, for instance, Python is neither call by reference nor call
by value, it is call by object.

No, python is call by value, and it happens that all values are pointers.
Just like java, but without the primitive types, and like LISP, and like a
load of other languages. Python's parameter passing is NO DIFFERENT to
that in those languages, and those languages are ALL described as
call-by-value, so to claim that python does not use call-by-reference but
some random new 'call-by-object' convention is incorrect, unneccessary,
confusing and silly.

</rant>

I'm sure this has been argued over many times here, and we still
all have our different ideas, so please just ignore this post!

tom

--
So the moon is approximately 24 toasters from Scunthorpe.
Dec 13 '05 #13
Tom Anderson wrote:
On Tue, 13 Dec 2005, Steven D'Aprano wrote:

On Mon, 12 Dec 2005 18:51:36 -0600, Larry Bates wrote:

[snippidy-doo-dah]

variable is a character or a number". I figured that even if he is
coming from another language he knows the difference between "a given
variable" and the "contents of a give variable". I guess we will
see.... ;-). This list is so good, he gets BOTH questions answered.
The problem is, Python doesn't have variables (although it is
oh-so-tempting to use the word, I sometimes do myself). It has names in
namespaces, and objects.

In what sense are the names-bound-to-references-to-objects not variables?

In a very important sense, one which you should understand in order to
understand the nature of Python.

In C if you declare a variable as (for example) a character string of
length 24, the compiler will generate code that allocates 24 bytes to
this variable on the stack frame local to the function in which it's
declared. Similarly if you declare a variable as a double-length
floating point number the compiler will emit code that allocates 16
bytes on the local stack-frame.

In Python a name (*not* a "variable", though people do talk loosely
about "instance variables" and "class variables" just to be able to use
terms familiar to users of other to languages) is simply *bound* to a
value. The only storage that is required, therefore, is enough to hold a
pointer (to the value currently bound to the name). Thus assignment
(i.e. binding to a name, as opposed to binding to an element of a data
structure) NEVER copes the object, it simply stores a pointer to the
bound object in the part of the local namespace allocated to that name.
It be a subtle difference, but an important one.

No, it's just spin, bizarre spin for which i can see no reason. Python has
variables.

You appear very confident of your ignorance ;-)
That's why, for instance, Python is neither call by reference nor call
by value, it is call by object.

No, python is call by value, and it happens that all values are pointers.
Just like java, but without the primitive types, and like LISP, and like a
load of other languages. Python's parameter passing is NO DIFFERENT to
that in those languages, and those languages are ALL described as
call-by-value, so to claim that python does not use call-by-reference but
some random new 'call-by-object' convention is incorrect, unneccessary,
confusing and silly.

</rant>

I'm sure this has been argued over many times here, and we still
all have our different ideas, so please just ignore this post!

Couldn't!

I do apologise, though, for any implication you assertions are based on
ignorance because you do demonstrate quite a sophisticated knowledge of
what goes on under the hood. As long as you can accept that "Python
'variables' are all references" then the rest is indeed semantics.

Of course it will be helpful for newcomers if we can adopt a standard
terminology ...

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Dec 13 '05 #14
Tom Anderson wrote:
In what sense are the names-bound-to-references-to-objects not variables?

In the sense that a variable has various meta-informations (at least a
type) while a Python name has no information. A Python name would be
equivalent to a C void pointer, it can mean *any*thing and has no
value/meaning by itself, only the object it references has.
Dec 13 '05 #15
Steve Holden wrote:
In Python a name (*not* a "variable", though people do talk loosely
about "instance variables" and "class variables" just to be able to use
terms familiar to users of other to languages) is simply *bound* to a
value. The only storage that is required, therefore, is enough to hold a
pointer (to the value currently bound to the name).

in tom's world, the value of an object is the pointer to the object, not the
object itself, so I'm not sure he can make sense of your explanation.

</F>

Dec 13 '05 #16
On Tue, 13 Dec 2005 15:28:32 +0000, Tom Anderson wrote:
On Tue, 13 Dec 2005, Steven D'Aprano wrote:
On Mon, 12 Dec 2005 18:51:36 -0600, Larry Bates wrote:

[snippidy-doo-dah]
variable is a character or a number". I figured that even if he is
coming from another language he knows the difference between "a given
variable" and the "contents of a give variable". I guess we will
see.... ;-). This list is so good, he gets BOTH questions answered.
The problem is, Python doesn't have variables (although it is
oh-so-tempting to use the word, I sometimes do myself). It has names in
namespaces, and objects.

In what sense are the names-bound-to-references-to-objects not variables?

Because saying "Python has variables" leads to nonsense like the following:

[snip]
That's why, for instance, Python is neither call by reference nor call
by value, it is call by object.

No, python is call by value, and it happens that all values are
pointers.

All values in Python are pointers???

So when I write:

name = "spam spam spam spam"

the value of the variable "name" is a pointer, and not a string. Riiight.

Call by value and call by reference have established meanings in
computer science, and Python doesn't behave the same as either of them.
Consider the following function:

def modify(L):
"Modify a list and return it."
L.append(None); return L

If I call that function:

mylist = range(10**10) # it is a BIG list
anotherlist = modify(mylist)

if the language is call by value, mylist is DUPLICATED before being
passed to the function. That does not happen in Python. Consequently,
expected behaviour of a call by value language is that anotherlist and
mylist will be different. That is not true in Python either. So Python is
not call by value.

But neither is it call by reference. If it were call by reference, I could
write something like this:
def increment(n):
"""Add one to the argument changing it in place."""
# In Pascal, I would need the var keyword to get this behaviour,
# but Python is call by reference so all variables are passed
# by reference.
n += 1

x = 1
increment(x)
assert x == 2

but that doesn't work in Python either.

So Python behaves demonstrably different from BOTH call by value and call
by reference. Consequently, it is neither of them.

The conceptual problem you are having is that you are conflating the
object model of Python the language with the mechanism of the underlying C
implementation, which does simply pass pointers around. But when
discussing the behaviour of Python, what counts is the behaviour of Python
code, not the underlying C mechanism -- which may be different than the
underlying Java mechanism in JPython, or Python mechanism in PyPython.
[snip]
I'm sure this has been argued over many times here, and we still
all have our different ideas, so please just ignore this post!

I'd love to, but unfortunately I've already hit send on my reply.

--
Steven.

Dec 13 '05 #17
Steven D'Aprano wrote:
name = "spam spam spam spam"

the value of the variable "name" is a pointer, and not a string. Riiight.
Yes, it's a reference to an object of type string holding the value
<spam spam spam spam>
def increment(n):
"""Add one to the argument changing it in place."""
# In Pascal, I would need the var keyword to get this behaviour,
# but Python is call by reference so all variables are passed
# by reference.
n += 1

x = 1
increment(x)
assert x == 2

but that doesn't work in Python either.

That example is mightily flawed since Python's integers are immutable
objects.

Here, python creates a new integer object of value "n+1" and binds the
_local_ name "n" to this new object. n isn't bound to it's initial
object anymore (the one x is bound to), and therefore can't modify it.

Now use a mutable type instead of an immutable int and you'll notice a
pass-by-reference behavior.
Dec 13 '05 #18
Xavier Morel wrote:
Now use a mutable type instead of an immutable int and you'll notice a
pass-by-reference behavior.

python passes a reference to the value, not a reference to the variable.
call-by-reference usually refers to the latter. see e.g.

http://foldoc.org/?call-by-reference

</F>

Dec 13 '05 #19
On Tue, 13 Dec 2005 23:21:02 +0100, Xavier Morel wrote:
Steven D'Aprano wrote:
name = "spam spam spam spam"

the value of the variable "name" is a pointer, and not a string. Riiight.
Yes, it's a reference to an object of type string holding the value
<spam spam spam spam>

The underlying C implementation might be that, but we're not talking about
the underlying C implementation, where talking about the Python level.
Python does not have pointers. If you want to go down the path of
treating Python as if it were the underlying implementation, I'll just
argue that everything in Python is untyped bytes, because that's the way
the machine code executed by the CPU sees things.

def increment(n):
"""Add one to the argument changing it in place."""
# In Pascal, I would need the var keyword to get this behaviour,
# but Python is call by reference so all variables are passed
# by reference.
n += 1

x = 1
increment(x)
assert x == 2

but that doesn't work in Python either.

That example is mightily flawed since Python's integers are immutable
objects.

That's the *reason* why the behaviour doesn't work. But the *fact* that it
doesn't work is enough to prove that Python is not call by reference. Call
by reference *demands* the ability to do that sort of thing.
Now use a mutable type instead of an immutable int and you'll notice a
pass-by-reference behavior.

Wrong. Will this example clarify things?

def modify_in_place(obj):
"""Modify an arbitrary object in place."""
obj = None

x = [1, 2, 3] # mutable object
modify_in_place(x)
assert x is None
Doesn't work either.

Sometimes call by object behaves like call by reference, and sometimes
like call by value, but it is not either of them.

--
Steven.

Dec 13 '05 #20
Steven D'Aprano <st***@REMOVETHIScyber.com.au> writes:
But neither is it call by reference. If it were call by reference, I could
write something like this:

def increment(n):
"""Add one to the argument changing it in place."""
# In Pascal, I would need the var keyword to get this behaviour,
# but Python is call by reference so all variables are passed
# by reference.
n += 1

x = 1
increment(x)
assert x == 2

but that doesn't work in Python either.
Yes, it doesn't work, but the reason it doesn't work isn't because
Python doesn't do call-by-reference.
So Python behaves demonstrably different from BOTH call by value and call
by reference. Consequently, it is neither of them.

Right. *Python* behaves differently. That's not the same thing as
Python's calling behaving differently. If you choose objects that are
behave the same in both languages, Python behaves *exactly* like
call-by-reference.

You can show the same difference in behavior between Python and C (for
example) without using a function call.

Here's C:

#include <assert.h>

main() {
int i, *ref ;
i = 1 ;
ref = &i ; /* Save identity of i */
i = 2 ;
assert(ref == &i) ;
}

This runs just fine; i is the same object throughout the program.

On the other hand, the equivalent Python:
i = 1
ref = id(i) # Save the identity of i
i = 2
assert ref == id(i) Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError

Blows up - i is no longer the same object.

Python does call by reference, which means that it passes pointers to
objects by value. C is call by value, faking call by reference by
passing reference values. The real difference is that in C, you can
get a reference to a variable to pass, allowing you to change the
variable. In python, you can't get a reference to a name (one of the
reasons we call them "names" instead of "variables"), so you can't
pass a value that will let the called function change it.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Dec 14 '05 #21
Mike Meyer wrote:
So Python behaves demonstrably different from BOTH call by value and call
by reference. Consequently, it is neither of them.

Right. *Python* behaves differently. That's not the same thing as
Python's calling behaving differently. If you choose objects that are
behave the same in both languages, Python behaves *exactly* like
call-by-reference.

This would possibly be a valid argument if Python
*only* had such objects that behaved the same in call
by reference languages, but it doesn't. It also has
objects which behave differently. Just because Python
can, in certain restricted circumstances, act like call
by reference doesn't mean it is call by reference,
because there are a whole swag of circumstances where
Python _can't_ act like call by reference.
You can show the same difference in behavior between Python and C (for
example) without using a function call.

Here's C:

#include <assert.h>

main() {
int i, *ref ;
i = 1 ;
ref = &i ; /* Save identity of i */
i = 2 ;
assert(ref == &i) ;
}

This runs just fine; i is the same object throughout the program.

On the other hand, the equivalent Python:

i = 1
ref = id(i) # Save the identity of i
i = 2
assert ref == id(i)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError
Blows up - i is no longer the same object.

Your argument seems to me like some sort of reverse
bizarro "looks like a duck" argument: since Python
_doesn't_ behave like call by reference, it must _be_
call by reference.

Python does call by reference, which means that it passes pointers to
objects by value.

You are confusing the underlying implementation in C
with Python the language. I couldn't care less whether
the underlying implementation allows call by reference
or not. That is simply irrelevent to the question of
whether Python does call by reference.

Python doesn't have a pointer object type. There is an
implementation of Python written in pure Python. That
demonstrates that there is at least one implementation
of Python where it is demonstrably _not_ true that
Python "passes pointers to objects by value".

What do you think that does to your argument?

--
Steven.

Dec 14 '05 #22
Steven D'Aprano wrote:
def modify_in_place(obj):
"""Modify an arbitrary object in place."""
obj = None

x = [1, 2, 3] # mutable object
modify_in_place(x)
assert x is None
Doesn't work either.

To be fair, this isn't because the function is not pass by reference,
but because the assignment operator reassigns the reference rather than
altering the referent, and thus modify_in_place doesn't actually
contain any modifying operations. With a good understanding of what
Python's assignment operator actually does, (I believe) you can view
Python as pass-by-reference without any semantic problems.

--
Ben Sizer

Dec 14 '05 #23
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
Mike Meyer wrote:
So Python behaves demonstrably different from BOTH call by value and call
by reference. Consequently, it is neither of them.

Right. *Python* behaves differently. That's not the same thing as
Python's calling behaving differently. If you choose objects that are
behave the same in both languages, Python behaves *exactly* like
call-by-reference.

This would possibly be a valid argument if Python *only* had such
objects that behaved the same in call by reference languages, but it
doesn't. It also has objects which behave differently. Just because
Python can, in certain restricted circumstances, act like call by
reference doesn't mean it is call by reference, because there are a
whole swag of circumstances where Python _can't_ act like call by
reference.

You've got this exactly backwards. Every object in Python behaves the
same way as similar objects in call-by-reference lannguages. Those
languages have objects which have no analogue in Python. If you use
one of them as your example of what "call-by-reference" does, it will
of course have behavior that can't be reproduced in Python. That isn't
because Python isn't call-by-reference; it's because Python doesn't
have objects that behave like the one you're using for an example.
You can show the same difference in behavior between Python and C (for
example) without using a function call.
Here's C:
#include <assert.h>
main() {
int i, *ref ;
i = 1 ;
ref = &i ; /* Save identity of i */
i = 2 ;
assert(ref == &i) ;
}
This runs just fine; i is the same object throughout the program.
On the other hand, the equivalent Python:
>i = 1
>ref = id(i) # Save the identity of i
>i = 2
>assert ref == id(i)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError
Blows up - i is no longer the same object.

Your argument seems to me like some sort of reverse bizarro "looks
like a duck" argument: since Python _doesn't_ behave like call by
reference, it must _be_ call by reference.

You're right in that this doesn't demonstrate that Python has
call by referece. What it shows is that your example of why Python
isn't call by referencde is invalid: your example depends on an object
behavior that doesn't exist in Python, no matter what calling
convention it uses.
Python does call by reference, which means that it passes pointers to
objects by value.

You are confusing the underlying implementation in C with Python the
language. I couldn't care less whether the underlying implementation
allows call by reference or not. That is simply irrelevent to the
question of whether Python does call by reference.
Python doesn't have a pointer object type. There is an implementation
of Python written in pure Python. That demonstrates that there is at
least one implementation of Python where it is demonstrably _not_ true
that Python "passes pointers to objects by value".
What do you think that does to your argument?

I think you're right in the first paragraph - that it's discussing the
implementation, and is thus totally irrelevant to the question of
whether or not python does call by reference.

To restate the first paragraph: Python's calling semantics are a
proper subset of call-by-reference. If the object passed has the same
behavior as it does in a call-by-reference lanuage, then the behavior
of the argument is the same as it is in the call-by-reference
language. You can argue that one of the missing things is crucial to
the definition of call by reference, in which case we disagree about
the meaning of call by reference, and we can stop there. Or you can
argue that there is some object in Python that behaves the same way in
both Python and a call by reference that does not behave the same way
when passed as an argument. I'm still waiting for an example of that.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Dec 14 '05 #24
On Tue, 13 Dec 2005, Fredrik Lundh wrote:
Steve Holden wrote:
In Python a name (*not* a "variable", though people do talk loosely
about "instance variables" and "class variables" just to be able to use
terms familiar to users of other to languages) is simply *bound* to a
value. The only storage that is required, therefore, is enough to hold
a pointer (to the value currently bound to the name).
in tom's world, the value of an object is the pointer to the object, not
the object itself,

If you meant "he value of a *variable* is a pointer to an object, not the
object itself", then bingo, yes, that's what it's like in my world.
so I'm not sure he can make sense of your explanation.

The explanation makes perfect sense - i think the names-values-bindings
terminology is consistent, correct and clear. It's just that i think that
the variables-objects-pointers terminology is equally so, so i object to
statements like "python is not pass-by-value".

tom

--
The sky above the port was the colour of television, tuned to a dead
channel
Dec 14 '05 #25
On Tue, 13 Dec 2005, Xavier Morel wrote:
Tom Anderson wrote:
In what sense are the names-bound-to-references-to-objects not
variables?
In the sense that a variable has various meta-informations (at least a
type)

No. In a statically typed language (or possibly only a manifestly typed
language), a variable has a type; in an untyped language, it doesn't.
while a Python name has no information. A Python name would be
equivalent to a C void pointer, it can mean *any*thing and has no
value/meaning by itself, only the object it references has.

Quite right - so it's also equivalent to a LISP, Smalltalk or Objective C
(to mention but a few) variable?

tom

--
The sky above the port was the colour of television, tuned to a dead
channel
Dec 14 '05 #26
On Tue, 13 Dec 2005, Mike Meyer wrote:
You can show the same difference in behavior between Python and C (for
example) without using a function call.
Really? You certainly don't do that with the code below.
Here's C:

#include <assert.h>

main() {
int i, *ref ;
i = 1 ;
ref = &i ; /* Save identity of i */
Here, ref is a reference to a variable.
i = 2 ;
assert(ref == &i) ;
Here, you're comparing the addresses of variables.
}

This runs just fine; i is the same object throughout the program.

On the other hand, the equivalent Python:
i = 1
ref = id(i) # Save the identity of i
Here, ref is a reference to a value.
i = 2
assert ref == id(i)
Here, you're comparing values.
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError

Blows up - i is no longer the same object.

Right, because the two bits of code are doing quite different things.
Python does call by reference, which means that it passes pointers to
objects by value.
That's not what call by reference is - call by reference is passing
pointers to *variables* by value.
C is call by value, faking call by reference by passing reference
values. The real difference is that in C, you can get a reference to a
variable to pass, allowing you to change the variable. In python, you
can't get a reference to a name (one of the reasons we call them "names"
instead of "variables"), so you can't pass a value that will let the
called function change it.

Kinda. Here's a python translation of Steven's incrementing function
example:

def increment(n):
"""Add one to the argument changing it in place."""
# python (rightly) doesn't have references to variables
# so i will use a 2-tuple (namespace, name) to fake them
# n should be such a 2-tuple
n_namespace = n[0]
n_name = n[1]
n_namespace[n_name] += 1

x = 1
increment((locals(), "x"))
assert x == 2

This is an evil, festering, bletcherous hack, but it is a direct
translation of the use of pass-by-reference in C.

As a bonus, here's a similarly literal python translation of your C
program:
i = 1
ref = "i"
i = 2
assert ref == "i"

tom

--
The sky above the port was the colour of television, tuned to a dead
channel
Dec 14 '05 #27
On Wed, 14 Dec 2005, Steven D'Aprano wrote:
On Tue, 13 Dec 2005 15:28:32 +0000, Tom Anderson wrote:
On Tue, 13 Dec 2005, Steven D'Aprano wrote:
On Mon, 12 Dec 2005 18:51:36 -0600, Larry Bates wrote:

[snippidy-doo-dah]

variable is a character or a number". I figured that even if he is
coming from another language he knows the difference between "a given
variable" and the "contents of a give variable". I guess we will
see.... ;-). This list is so good, he gets BOTH questions answered.

The problem is, Python doesn't have variables (although it is
oh-so-tempting to use the word, I sometimes do myself). It has names in
namespaces, and objects.
In what sense are the names-bound-to-references-to-objects not variables?

Because saying "Python has variables" leads to nonsense like the following:

[snip]
That's why, for instance, Python is neither call by reference nor call
by value, it is call by object.

No, python is call by value, and it happens that all values are
pointers.

All values in Python are pointers???

Right.
So when I write:

name = "spam spam spam spam"

the value of the variable "name" is a pointer, and not a string. Riiight.
Right.
Call by value and call by reference have established meanings in
computer science,
Right.
and Python doesn't behave the same as either of them.
Wrong. Python behaves exactly like call by value, just like Smalltalk,
Objective C, LISP, Java, and even C.
Consider the following function:

def modify(L):
"Modify a list and return it."
L.append(None); return L

If I call that function:

mylist = range(10**10) # it is a BIG list
anotherlist = modify(mylist)

if the language is call by value, mylist is DUPLICATED before being
passed to the function.
Wrong. The value of mylist is a pointer to a list, and that's what's
passed to the function. The same analysis applies to the rest of your
example.
The conceptual problem you are having is that you are conflating the
object model of Python the language with the mechanism of the underlying
C implementation, which does simply pass pointers around.

No, i'm not, i'm really not. Thinking in terms of variables, pointers and
objects is a simple, consistent and useful abstract model of computation
in python. If you like, we can use the word 'reference' instead of
'pointer' - i guess a lot of people who came from C (which i didn't) are
hung up on the idea that a pointer is a memory address, rather than just a
conceptual thing which goes from a variable to an object; the trouble is
that then we remind people of 'call by reference', and it all goes to pot.

I think the background thing is the kicker here. I'm guessing you come
from C, where pointers are physical and explicit, you can have a variable
which really does contain an object, etc, and so for you, applying those
terms to python is awkward. I come from java, where all pointers are
abstract (in the sense of being opaque) and implicit, and variables only
ever contain pointers (unless they're primitive - but that's an
implementation detail), so the terminology carries over to python quite
naturally.
I'm sure this has been argued over many times here, and we still all
have our different ideas, so please just ignore this post!

I'd love to, but unfortunately I've already hit send on my reply.

Fair enough. Sorry about all this. In future, i'm going to send posts
which i *know* will generate heat but no light straight to /dev/null ...

tom

--
The literature, especially in recent years, has come to resemble `The
Blob', growing and consuming everything in its path, and Steve McQueen
isn't going to come to our rescue. -- The Mole
Dec 14 '05 #28
On Tue, 13 Dec 2005, Steve Holden wrote:
Tom Anderson wrote:
On Tue, 13 Dec 2005, Steven D'Aprano wrote:
On Mon, 12 Dec 2005 18:51:36 -0600, Larry Bates wrote:

[snippidy-doo-dah]

variable is a character or a number". I figured that even if he is
coming from another language he knows the difference between "a given
variable" and the "contents of a give variable". I guess we will see....
;-). This list is so good, he gets BOTH questions answered.

The problem is, Python doesn't have variables (although it is
oh-so-tempting to use the word, I sometimes do myself). It has names
in namespaces, and objects.
In what sense are the names-bound-to-references-to-objects not variables?

In a very important sense, one which you should understand in order to
understand the nature of Python.

In C

Stop. How am i going to understand the nature of python by reading about
C? Python is not C. What C does in the privacy of its own compilation unit
is of no concern to us.
if you declare a variable as (for example) a character string of length
24, the compiler will generate code that allocates 24 bytes to this
variable on the stack frame local to the function in which it's
declared. Similarly if you declare a variable as a double-length
floating point number the compiler will emit code that allocates 16
bytes on the local stack-frame.
True but irrelevant.
In Python a name [...] is simply *bound* to a value. The only storage
that is required, therefore, is enough to hold a pointer (to the value
currently bound to the name). Thus assignment (i.e. binding to a name,
as opposed to binding to an element of a data structure) NEVER copes the
object, it simply stores a pointer to the bound object in the part of
the local namespace allocated to that name.
Absolutely true. I'm not saying your terminology is wrong - i'm pointing
out that mine is also right.

Basically, we're both saying:

"""In python, the universe consists of things; in order to manipulate
them, programs use hands, which hold things - the program is expressed as
actions on hands, which direct actions on things at runtime. Although it
appears at first glance that there is a direct correspondence between
hands and things, it is crucial to realise that the relationship is
mediated by a holding - the hand identifies a particular holding, which in
turn identifies a particular thing. So, when we make a function call, and
specify hands as parameters, it is not the hands themselves, *or* the
things, that get passed to the function - it's the holdings. Similarly,
when we make an assignment, we are not assigning a thing - no things are
touched by an assignment - but a holding, so that the hand assigned to
ends up gripping a different thing.

There is in fact another layer of indirection - the programmer refers to
hands using strings, but this is just part of the language used to express
programs textually: the correspondence between these strings and the hands
they refer to is called a manual. The manual which applies at any point in
a program is determined lexically - it is the manual corresponding to the
function enclosing that point, or the global manual, if it is at the top
level.

"""

Where you can substitute either of:

steves_terminology = {
"thing": "value",
"hand": "name",
"hold": "are bound to",
"holding": "binding",
"gripping": "being bound to",
"manual": "namespace"
}

toms_terminology = {
"thing": "object",
"hand": "variable",
"hold": "point to",
"holding": "pointer",
"gripping": "pointing to",
"manual": "scope"
}

Using:

def substitute(text, substitutions):
substituands = substitutions.keys()
# to handle substituands which are prefixes of other substituands:
substituands.sort(lambda a, b: -cmp(len(a), len(b)))
for substituand in substituands:
text = text.replace(substituand, substitutions[substituand])
return text

I'd then point out that my terminology is the one used in all other
programming languages, including languages whose model is the same as
python's, and so we should use it for consistency's sake. I guess the
argument for your terminology is that it's less confusing to C programmers
who don't realise that the * in *foo is now implicit.
It be a subtle difference, but an important one.

No, it's just spin, bizarre spin for which i can see no reason. Python
has variables.

You appear very confident of your ignorance ;-)

You appear to be very liberal with your condescension.

Steering rapidly away from further ad hominem attacks ...
I'm sure this has been argued over many times here, and we still all have
our different ideas, so please just ignore this post!

Couldn't!

I do apologise, though, for any implication you assertions are based on
ignorance because you do demonstrate quite a sophisticated knowledge of
what goes on under the hood. As long as you can accept that "Python
'variables' are all references" then the rest is indeed semantics.

Right. I think we just agreed.
Of course it will be helpful for newcomers if we can adopt a standard
terminology ...

That's certainly true. We should therefore adopt my terminology as
standard.

:)

tom

--
The literature, especially in recent years, has come to resemble `The
Blob', growing and consuming everything in its path, and Steve McQueen
isn't going to come to our rescue. -- The Mole
Dec 14 '05 #29
On Wed, 14 Dec 2005 12:51:43 -0500, Mike Meyer wrote:
To restate the first paragraph: Python's calling semantics are a
proper subset of call-by-reference. If the object passed has the same
behavior as it does in a call-by-reference lanuage, then the behavior
of the argument is the same as it is in the call-by-reference
language. You can argue that one of the missing things is crucial to
the definition of call by reference, in which case we disagree about
the meaning of call by reference, and we can stop there. Or you can
argue that there is some object in Python that behaves the same way in
both Python and a call by reference that does not behave the same way
when passed as an argument. I'm still waiting for an example of that.

fight and point you at two gentlemen who have forgotten more about
computer science than I'm ever likely to learn:

Thanks to Fredrik:

[quote]
the only thing you need to know is that Python's model is neither "call by
value" nor "call by reference"; the most accurate description is instead
CLU's "call by object" or "call by sharing". Or, if you prefer, "call by
object reference".
[end quote]

http://effbot.org/zone/call-by-object.htm

And from the tutorial by Guido:

[quote]
The actual parameters (arguments) to a function call are introduced
in the local symbol table of the called function when it is called; thus,
arguments are passed using call by value (where the value is always an
object reference, not the value of the object). [Footnote: Actually, call
by object reference would be a better description, since if a mutable
object is passed, the caller will see any changes the callee makes to it
(items inserted into a list).]
[end quote]

http://docs.python.org/tut/node6.html#tex2html2

--
Steven.

Dec 14 '05 #30
"Ben Sizer" <ky*****@gmail.com> wrote:
Steven D'Aprano wrote:
def modify_in_place(obj):
"""Modify an arbitrary object in place."""
obj = None

x = [1, 2, 3] # mutable object
modify_in_place(x)
assert x is None
Doesn't work either.

To be fair, this isn't because the function is not pass by reference,
but because the assignment operator reassigns the reference rather than
altering the referent, and thus modify_in_place doesn't actually
contain any modifying operations. With a good understanding of what
Python's assignment operator actually does, (I believe) you can view
Python as pass-by-reference without any semantic problems.

What he said!

While I agree (with another post) that there seems to be
a difference in perspective that depends on what language
you were using when you first heard these terms, in the
end it really seems sort of almost disingenuous to argue
that the "value" in question is actually a pointer. (The
pointer is in a practical sense a reference, so what if we
say "pass by reference value?!"

I would like to argue that "value" basically means the
computational effect. In "s = a + b", the value of "b"
is whatever ends up applied to that "+" operator. In
isolation, the value of some object is its computational
potential - the object isn't its value, rather the
implementation of the value. Parameter passing isn't
a computation in this sense, and it doesn't make sense
for it to have its own interpretation of "value".

--

Historically, the way I remember it, there was a time not too
long ago when GvR and his minions sort of dismissed the idea
that you needed to understand the reference/object model from
the outset. I mean, obviously you need to get there eventually
if you're going to be a hard core Python programmer, but they
wanted to see people learning to write programs, without being
encumbered by knowledge of implementation details, and ideas
about the difference between "variable" and "binding" are

It depends on your ambitions, I suppose, whether that's really
a good idea, since there's no question that some understanding
of the principles involved has to come fairly early. But I think
we really lose out when we try to make it be about the words -
"Python doesn't have variables"/"Does too", "Python passes by
value"/"Does not", etc. When the words really clearly express
the right thing to anyone with a reasonable background, that's
great. But usually, they don't.

Donn Cave, do**@u.washington.edu
Dec 14 '05 #31
Donn Cave wrote:
While I agree (with another post) that there seems to be
a difference in perspective that depends on what language
you were using when you first heard these terms, in the
end it really seems sort of almost disingenuous to argue
that the "value" in question is actually a pointer.
The word "value" has a defined meaning in python:

http://docs.python.org/ref/objects.html
(The pointer is in a practical sense a reference, so what
if we say "pass by reference value?!"

"call by object reference" ?

as the CLU folks noted some thirty years ago (my emphasis):

"IN PARTICULAR IT IS NOT CALL BY VALUE because mutations
of arguments performed by the called routine will be visible to
the caller. And IT IS NOT CALL BY REFERENCE because access
is not given to the variables of the caller, but merely to certain
objects."

Arguing that "as long as I can define the word value/reference, it's
call-by-value/reference" is somewhat disingenuous, indeed.

</F>

Dec 14 '05 #32
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. However, if you use lists, then it only passes a pointer, or
tuples as well. Ei, I just ran this through the python IDE.
x="Test"
def modstring(var): var="Blah" modstring(x)
print x

Test

This seems to indicate that the variable is copied, as the value didn't
change. Weither or not Python keeps the variables as pointers
internally, it doesn't really matter. Actually, all languages do such
things, except assembly.

I just ran the test on lists and tuples, it was the same results,
nothing moved.

Other than this, I basically see a fight on terminology, and that's
that.

Dec 15 '05 #33
Tom Anderson <tw**@urchin.earth.li> writes:
Python does call by reference, which means that it passes pointers
to objects by value. That's not what call by reference is - call by reference is passing
pointers to *variables* by value.

In which case, Python can't do call-by-reference at all, because it
doesn't have variable.

Of course, I think call-by-reference is passing references to
*objects* by value.
As a bonus, here's a similarly literal python translation of your C
program:
i = 1
ref = "i"
i = 2
assert ref == "i"

I claim that's not correct, because ref can be used to change i in any
context in C. In your version, ref can only be used to change i if you
have access to the namespace that i lives in. In my version, ref can't
be used to change i at all.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Dec 15 '05 #34
Donn Cave <do**@u.washington.edu> writes:
I would like to argue that "value" basically means the
computational effect. In "s = a + b", the value of "b"
is whatever ends up applied to that "+" operator. In
isolation, the value of some object is its computational
potential - the object isn't its value, rather the
implementation of the value. Parameter passing isn't
a computation in this sense, and it doesn't make sense
for it to have its own interpretation of "value".
Now you're hovering on the edge of call by name.
Historically, the way I remember it, there was a time not too
long ago when GvR and his minions sort of dismissed the idea
that you needed to understand the reference/object model from
the outset. I mean, obviously you need to get there eventually
if you're going to be a hard core Python programmer, but they
wanted to see people learning to write programs, without being
encumbered by knowledge of implementation details, and ideas
about the difference between "variable" and "binding" are

No, they're not. They're a fundamental part of the semantics of the
language. But you are right - you should be able to learn how to
program in Python without having to learn about those thing. The fact
is, you can do that - if you don't have any preconcieved notions about
what the names are and how they behave. If you have to unlearn things
from another language (like that variables have types, or values that
can be changed), then you'll need the difference explained the first
time the difference is noticable.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Dec 15 '05 #35

Tuvas wrote:
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. However, if you use lists, then it only passes a pointer, or
tuples as well. Ei, I just ran this through the python IDE.
x="Test"
def modstring(var): var="Blah" modstring(x)
print x
Test

This seems to indicate that the variable is copied, as the value didn't
change. Weither or not Python keeps the variables as pointers
internally, it doesn't really matter. Actually, all languages do such
things, except assembly.

No. They are not copied, at least not at function invokation. The
parameter in the functions scope got rebound(that is the term python
people like to use) to a new value(or object in python term as
everything in python is an object) if you use the "=" operator.

x="test"
y=["test"]
def mod_1(v):
v="blah"

def mod_2(v):
v[0]="blah"

mod_1(x)
print x
mod_1(y)
print y
mod_2(x)
print x
mod_2(y)
print y

You can see that neither x or y changed with mod_1, regardless whether
it is mutable or not. mod_2(x) is an error as it kind of use 'v' as an
object pointer and invoke some method on it(the object) which doesn't
exist for x. mod_2(y) works as expected, because y in this case is sort
of an object which is a container which has the "[]" method.
I just ran the test on lists and tuples, it was the same results,
nothing moved.

Other than this, I basically see a fight on terminology, and that's
that.

Dec 15 '05 #36
"Tuvas" <tu*****@gmail.com> writes:
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, it doesn't copy them:
def same_object(x, x_id): .... return id(x) == x_id
.... a = "abc"
same_object(a, id(a)) True b = 1
same_object(b, id(b)) True b = 2 * 20
same_object(b, id(b)) True However, if you use lists, then it only passes a pointer, or
tuples as well. Ei, I just ran this through the python IDE.
It passes a reference to the object in both cases.
x="Test"
def modstring(var): var="Blah" modstring(x)
print x

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

Except that modstring didn't do anything to change the value of x. It
bound the name var in the modstring function to the string "Blah".
Weither or not Python keeps the variables as pointers internally, it
doesn't really matter. Actually, all languages do such things,
except assembly.
No, they don't. In a conventional language - including assembler - a
variable is a *compile-time* object that refers to a specific bit of
memory. Mentioning the name of the variable in your source causes code
to be emitted that loads the value stored in that memory. An
assignment statement causes code to be emitted to that stores a value
in that memory. By the time you get to run time, the variable per se
no longer exists - all references to it have been converted to
references to the memory it specifies. This is grossly
oversimplified, and not true for all languages, including some that
would otherwise be considered conventional.
Other than this, I basically see a fight on terminology, and that's
that.

Could well be.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Dec 15 '05 #37
Quoth Mike Meyer <mw*@mired.org>:
| Donn Cave <do**@u.washington.edu> writes:
....
|> Historically, the way I remember it, there was a time not too
|> long ago when GvR and his minions sort of dismissed the idea
|> that you needed to understand the reference/object model from
|> the outset. I mean, obviously you need to get there eventually
|> if you're going to be a hard core Python programmer, but they
|> wanted to see people learning to write programs, without being
|> encumbered by knowledge of implementation details, and ideas
|> about the difference between "variable" and "binding" are
|
| No, they're not. They're a fundamental part of the semantics of the
| language. But you are right - you should be able to learn how to
| program in Python without having to learn about those thing. The fact
| is, you can do that - if you don't have any preconcieved notions about
| what the names are and how they behave. If you have to unlearn things
| from another language (like that variables have types, or values that
| can be changed), then you'll need the difference explained the first
| time the difference is noticable.

Yes, it may be easier to learn from a blank slate, though I wouldn't
be too sure. But that is kind of beside the point (are you trying to
answer too many messages per day here?) Either you have to learn it,
or you don't.

Eventually, of course you do have to learn it. At some point you're
confronted with the need to predict what will happen in one of those
perennial examples like a = [], b = a, a.append(c). If you can predict
results accurately every time, then whether you learned it by reading
the documentation or by experimentation, whether you learned it in CS
terminology or understand it in some non-verbal way, in any case you
have learned something about the language itself.

The question is whether basically everyone needs to get there, or we
can expect the masses to use the language _without understanding it_
in this sense, without understanding the language-specific stuff.
I don't know how important that is, I guess it depends on how real
the CP4E world is ever going to be, but I think it's wishful thinking
to expect that to work with Python.

Donn Cave, do**@drizzle.com
Dec 15 '05 #38
Donn Cave wrote:
Quoth Mike Meyer <mw*@mired.org>:
| Donn Cave <do**@u.washington.edu> writes:
...

The question is whether basically everyone needs to get there, or we
can expect the masses to use the language _without understanding it_
in this sense, without understanding the language-specific stuff.
I don't know how important that is, I guess it depends on how real
the CP4E world is ever going to be, but I think it's wishful thinking
to expect that to work with Python.

Hear, hear. However you describe it Python is what it is, and this
interminable discussion about its similarities with and differences from
various concepts (most lately call by name/call by value) doesn't much
aid understanding for the majority.

The important question is not "what's that Python concept called in
other languages" but "do you understand how Python works".

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Dec 15 '05 #39
On Thu, 15 Dec 2005 08:22:37 +0000, Steve Holden wrote:
Hear, hear. However you describe it Python is what it is, and this
interminable discussion about its similarities with and differences from
various concepts (most lately call by name/call by value) doesn't much
aid understanding for the majority.

The important question is not "what's that Python concept called in
other languages" but "do you understand how Python works".

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?".
--
Steven.

Dec 15 '05 #40
On Wed, 14 Dec 2005 18:17:57 -0800, Tuvas wrote:
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.
x="Test"
def modstring(var): var="Blah" modstring(x)
print x
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
will also be confused or incomplete.

--
Steven.

Dec 15 '05 #41
<snip a bunch of stuff>
Terminology is important, because we understand the world through
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.

--
Steven.

--
http://mail.python.org/mailman/listinfo/python-list

Dec 16 '05 #42
On 12/15/05, Chris Mellon <ar*****@gmail.com> wrote:
<snip a bunch of stuff>
Terminology is important, because we understand the world through
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.

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

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.

--
Steven.

--
http://mail.python.org/mailman/listinfo/python-list

Dec 16 '05 #43
Chris Mellon <ar*****@gmail.com> writes:
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:
def inc(x): .... x = x + [1]
.... y = []
x = y
inc(y)
y [] x
[]

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
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
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Dec 16 '05 #44
Quoth Chris Mellon <ar*****@gmail.com>:
| <snip a bunch of stuff>
|> Terminology is important, because we understand the world through
|> 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, do**@drizzle.com
Dec 16 '05 #45
Steven D'Aprano wrote:
On Thu, 15 Dec 2005 08:22:37 +0000, Steve Holden wrote:

Hear, hear. However you describe it Python is what it is, and this
interminable discussion about its similarities with and differences from
various concepts (most lately call by name/call by value) doesn't much
aid understanding for the majority.

The important question is not "what's that Python concept called in
other languages" but "do you understand how Python works".

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

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Dec 16 '05 #46
Steven D'Aprano <st***@REMOVETHIScyber.com.au> wrote:
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
Dec 18 '05 #47

### This discussion thread is closed

Replies have been disabled for this discussion.