Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Objects in Python

210 views
Skip to first unread message

shaun

unread,
Aug 22, 2012, 10:13:34 AM8/22/12
to
I'm having an issue its my first time using python and i set up a class one of the methods is supposed to return a string but instead returns:

<bound method Param.returnString of <Param.Param instance at 0x00C
389E0>>

Im very new to python and the object orientated feature doesnt seem to be as well put together as Java. Can anyone help with this problem?

Joel Goldstick

unread,
Aug 22, 2012, 10:31:09 AM8/22/12
to shaun, pytho...@python.org
> --
> http://mail.python.org/mailman/listinfo/python-list

It looks like you didn't add parens to the end of your call. Show us
your code. with the traceback

--
Joel Goldstick

Jussi Piitulainen

unread,
Aug 22, 2012, 10:31:52 AM8/22/12
to
I bet you are trying to call the method, returnString, without the
parentheses that enclose the parameters (and without any @property
stuff in the class).

>>> Para('dox').myWev
<bound method Para.myWev of <Para.Para object at 0xb7191dac>>
>>> Para('dox').myWev()
'dox'

Peter Otten

unread,
Aug 22, 2012, 10:36:00 AM8/22/12
to pytho...@python.org
It's definitely too early for you to draw conclusions ;)

> Can anyone help with this problem?

You have successfully created a bound method, now you need to invoke it:

>>> class Param(object):
... def returnString(self):
... return "hello"
...
>>> p = Param()
>>> p.returnString
<bound method Param.returnString of <__main__.Param object at
0x7facb3a16a50>>
>>> p.returnString()
'hello'

Unlike some other langages Python does not implicitly invoke functions or
methods. That makes it easy to pass them around like any other object.




lipska the kat

unread,
Aug 22, 2012, 10:59:25 AM8/22/12
to
On 22/08/12 15:13, shaun wrote:

[snip]

> Im very new to python and the object orientated feature doesnt seem to be as well put together as Java. Can anyone help with this problem?

From one Java head to another I suggest you park what you know about
Java and approach Python with a clear mind.

Python is not Java and Java is not Python, that much has become clear.
Python has actually been around longer than Java and contains many
features you will be familiar with, serialization and introspection to
name but two. The whole 'everything is an object' thing is a bit strange
at first but actually it just means that everything you write is wrapped
up in a component that exposes various standard methods and attributes,
you treat functions as Objects and modules as Objects and even your
classes will automagically sprout new attributes and properties, at
least that's what I've discovered so far.

There is no real enforced concept of information hiding, no binding of
type to variable in fact no concept of typing at all as far as I can
see. No interfaces and no subtype polymorphism (Python has 'Duck Type'
polymorphism and I haven't really explored all the ramifications of this
yet). It does however have multiple inheritance.

In trying to get a handle on the language it has helped me to think of
Python as a friendly interface onto the C programming language, it may
or may not help you

There are some very experienced pythonistas here and I'm sure you will
get the help you need. There is a tutor mailing list and a great first
starter is Dive into Python (google it)

I can't say that Python will replace Java for me, I've been using Java
since version 1, but it's got a good standard library and good support
here and on the mailing list ... and it supports Unicode :-)

I like it, give it a chance and you will probably like it too.

lipska

--
Lipska the Kat�: Troll hunter, sandbox destroyer
and farscape dreamer of Aeryn Sun

John Gordon

unread,
Aug 22, 2012, 11:03:51 AM8/22/12
to
In <18409992-1e28-4721...@googlegroups.com> shaun <shaun.w...@gmail.com> writes:

> I'm having an issue its my first time using python and i set up a class one of the methods is supposed to return a string but instead returns:

> <bound method Param.returnString of <Param.Param instance at 0x00C
> 389E0>>

It looks like you're referencing the method object itself, instead of
calling it method. In other words, you've left off the parentheses.

I.e. you're doing something like this:

print my_object.foo

Instead of this:

print my_object.foo()

--
John Gordon A is for Amy, who fell down the stairs
gor...@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

shaun

unread,
Aug 22, 2012, 11:25:36 AM8/22/12
to
Here is some code:
//////////////////////////This is the object I want to create:
#!/usr/bin/python
import cx_Oracle
import sys
import time
import datetime


class batchParam:

def __init__(self,array):
self.array=array


def breakuparray(self):
for row in self.array:
mer = row[0].ljust(25, ' ')
merc = row[1].ljust(13, ' ')
mertype = row[2]
merloc = row[3]
mercount = row[4]
mersec = row[5]
acq = row[6]



def returnBatch(self):
self.breakuparray()
return "\x01001\x0251.%s%s%s%s%s%s%s%s\x03" % (mer, merc, mertype, merloc, mercount, mersec, acq);


//////////////////////////////////////Here is the script I want to run the object in:


#!/usr/bin/python
import cx_Oracle
import sys
import time
import datetime
sys.path.append("C:\\Documents and Settings\\swiseman\\Desktop")
from batchParam import batchParam

term = sys.argv[1]
batch = sys.argv[2]

con = cx_Oracle.connect('databaseInfo')


cur = con.cursor()
cur.execute("SELECT * FROM SOME_TABLE))

results = cur.fetchall()

batchParam(results)
Batch=batchParam.returnBatch

print Batch

cur.close()

//////////////////////////////////////

Thanks,
Shaun

Chris Angelico

unread,
Aug 22, 2012, 11:47:46 AM8/22/12
to pytho...@python.org
On Thu, Aug 23, 2012 at 1:25 AM, shaun <shaun.w...@gmail.com> wrote:
> def breakuparray(self):
> for row in self.array:
> mer = row[0].ljust(25, ' ')
> merc = row[1].ljust(13, ' ')
> mertype = row[2]
> merloc = row[3]
> mercount = row[4]
> mersec = row[5]
> acq = row[6]

The "for ... in ..." construct is a loop. I'm not sure what you're
trying to accomplish here, but you're taking the last entry in
self.array and unpacking that as a nested array. Perhaps not what you
had in mind.

For what you're doing there, though, a class is overkill. Remember,
Python isn't Java; the most natural way to do everything isn't
necessarily to write a class that unpacks things and packs them up
again in a different way.

ChrisA

Dave Angel

unread,
Aug 22, 2012, 11:51:05 AM8/22/12
to shaun, pytho...@python.org
This creates an instance of batchParam, but doesn't save it anywhere.
So it's discarded immediately.

> Batch=batchParam.returnBatch
This tries to returns a reference to a static method of the class.
Without an object, you won't get access to normal instance methods;
there's no 'self'. And without parentheses, you won't even try to call
the method, right or wrong.

Probably you wanted something like:

obj = batchParam(results) #now obj is an instance
mystring = obj.returnBatch() #calls the method, and saves the
returned string
print mystring

>
> print Batch
>
> cur.close()
>
>

Other comments: Don't make the mistake of forcing every class into its
own source file. Unlike java, python has no such restrictions. It also
has ordinary functions, not part of any class. So if several classes
are related, go ahead and put them in a common file. Or keep them
separate, Python doesn't mind.

There are capitalization conventions: class names start with a capital
letter, and source code filenames do not. So the class you've got in
batchParam could be called BatchParam.

Neither of these matter much, but they make it easier for someone else
to see what you were trying to do.

It would also be helpful if you posted the complete error message (with
traceback), so we could more easily guess where in the code the problem
occurs. It can be useful to add a comment in the actual source you
post, since you have line numbers in your editor, and we don't in our
emails. But don't try to get cute with colors, as this is a text
forum. (that last comment may not apply to you, since you already used
a plain-text format for your message)

Python does have classmethod and staticmethod, but that's not usually
what you want, and not here.


--

DaveA

MRAB

unread,
Aug 22, 2012, 11:58:31 AM8/22/12
to pytho...@python.org
On 22/08/2012 15:59, lipska the kat wrote:
> On 22/08/12 15:13, shaun wrote:
>
> [snip]
>
>> Im very new to python and the object orientated feature doesnt seem to be as well put together as Java. Can anyone help with this problem?
>
> From one Java head to another I suggest you park what you know about
> Java and approach Python with a clear mind.
>
> Python is not Java and Java is not Python, that much has become clear.
> Python has actually been around longer than Java and contains many
> features you will be familiar with, serialization and introspection to
> name but two. The whole 'everything is an object' thing is a bit strange
> at first but actually it just means that everything you write is wrapped
> up in a component that exposes various standard methods and attributes,
> you treat functions as Objects and modules as Objects and even your
> classes will automagically sprout new attributes and properties, at
> least that's what I've discovered so far.
>
> There is no real enforced concept of information hiding, no binding of
> type to variable in fact no concept of typing at all as far as I can
> see.

strong typing != static typing

Python is strongly typed, but not statically typed.

> No interfaces and no subtype polymorphism (Python has 'Duck Type'
> polymorphism and I haven't really explored all the ramifications of this
> yet). It does however have multiple inheritance.
>
[snip]
Python doesn't have interfaces as in Java because it isn't statically
typed.

The idea behind Duck Typing is that the actual type doesn't matter; if
it supports the required method(s) and returns the expected type, then
that's good enough!

http://en.wikipedia.org/wiki/Duck_typing

lipska the kat

unread,
Aug 22, 2012, 12:10:51 PM8/22/12
to
On 22/08/12 16:58, MRAB wrote:
> On 22/08/2012 15:59, lipska the kat wrote:
>> On 22/08/12 15:13, shaun wrote:
>>
>> [snip]
>>
>>> Im very new to python and the object orientated feature doesnt seem
>>> to be as well put together as Java. Can anyone help with this problem?
>>
>> From one Java head to another I suggest you park what you know about
>> Java and approach Python with a clear mind.
[snip]
>
> strong typing != static typing
>
> Python is strongly typed, but not statically typed.
>
> > No interfaces and no subtype polymorphism (Python has 'Duck Type'
>> polymorphism and I haven't really explored all the ramifications of this
>> yet). It does however have multiple inheritance.
>>

[snip]

The residents can be pretty defensive as well :-)

Once again, no criticism intended.

Mark Lawrence

unread,
Aug 22, 2012, 12:13:29 PM8/22/12
to pytho...@python.org
On 22/08/2012 16:47, Chris Angelico wrote:
>
> For what you're doing there, though, a class is overkill. Remember,
> Python isn't Java; the most natural way to do everything isn't
> necessarily to write a class that unpacks things and packs them up
> again in a different way.
>
> ChrisA
>

This shows just how poor the Python documentation is. I can't find the
"overcoming brainwashing" section anywhere!!!

--
Cheers.

Mark Lawrence.

Mark Lawrence

unread,
Aug 22, 2012, 12:30:11 PM8/22/12
to pytho...@python.org
I'm lost. I see nothing defensive at all. I see a statement of fact.

--
Cheers.

Mark Lawrence.

Terry Reedy

unread,
Aug 22, 2012, 1:01:47 PM8/22/12
to pytho...@python.org
On 8/22/2012 10:59 AM, lipska the kat wrote:

> There is no real enforced concept of information hiding, no binding of
> type to variable in fact no concept of typing at all as far as I can
> see.

Given that type(valid_name) always returns a type(class), that is a
slightly strange statement. What is true is that there is no concept of
static type for names. In Python (and similar languages) type or class
is a property of objects, not names. This goes alone with names being
bound to objects rather than linear memory blocks. (Memory block is a
machine implementation of the abstraction 'information object'.) And
Python objects are more stfongly typed than in some other languages.
Names are only dynamically and indirectly typed when they are bound to
an object. Except for the few keyword names like None, True, etc, names
can be rebound to another object of another type.

--
Terry Jan Reedy

lipska the kat

unread,
Aug 22, 2012, 1:06:53 PM8/22/12
to
On 22/08/12 17:30, Mark Lawrence wrote:
> On 22/08/2012 17:10, lipska the kat wrote:
>> On 22/08/12 16:58, MRAB wrote:
>>> On 22/08/2012 15:59, lipska the kat wrote:
>>>> On 22/08/12 15:13, shaun wrote:
>>>>
>>>> [snip]
>>>>
>>>>> Im very new to python and the object orientated feature doesnt seem
>>>>> to be as well put together as Java. Can anyone help with this problem?

>>
>> The residents can be pretty defensive as well :-)
>>
>> Once again, no criticism intended.
>>
>> lipska
>>
>
> I'm lost. I see nothing defensive at all. I see a statement of fact.


You seem to be perpetually lost Mark ...

Ian Kelly

unread,
Aug 22, 2012, 1:29:18 PM8/22/12
to Python
In addition to the excellent feedback that Dave gave you:

On Wed, Aug 22, 2012 at 9:25 AM, shaun <shaun.w...@gmail.com> wrote:
> def breakuparray(self):
> for row in self.array:
> mer = row[0].ljust(25, ' ')
> merc = row[1].ljust(13, ' ')
> mertype = row[2]
> merloc = row[3]
> mercount = row[4]
> mersec = row[5]
> acq = row[6]

This loops over each row in self.array and stores the contents in a
set of variables called mer, merc, etc. Note that as written these
variables are *local* to the breakuparray method, not attributes of
the class. Also note that on each iteration, you reassign to the same
variables again, wiping out all the work you did on the previous
iteration. In the end, only the last row is stored in the local
variables, and then even that is wiped out when the method returns.

> def returnBatch(self):
> self.breakuparray()
> return "\x01001\x0251.%s%s%s%s%s%s%s%s\x03" % (mer, merc, mertype, merloc, mercount, mersec, acq);

This appears to be trying to use the same local variables from the
breakuparray method, but it can't. Those are out of scope here. If
you want to share these data between the breakuparray method and the
returnBatch method, you should either have breakuparray return them,
or you should store them as attributes on the object instance:
self.mer, self.merc, self.mertype, etc. (In Python, object attribute
storage is always explicit, never implicit as in Java and the rest of
the C++ family).

lipska the kat

unread,
Aug 22, 2012, 1:46:43 PM8/22/12
to
On 22/08/12 18:01, Terry Reedy wrote:
> On 8/22/2012 10:59 AM, lipska the kat wrote:
>
>> There is no real enforced concept of information hiding, no binding of
>> type to variable in fact no concept of typing at all as far as I can
>> see.
>
> Given that type(valid_name) always returns a type(class), that is a
> slightly strange statement.

[snip]

Well I'm a beginner so I'm allowed to make strange statements.
However I don't think it's that strange and here's why.

If, in a language, I find I am able to say

a = 1

then later, in the same scope I can say

a = "foo"

then later again in the same scope I can say

a = ([1,2,3], "xyz", True)

then, and I may be missing something here, to me, that doesn't say
'strongly typed' that says 'no typing constraints whatsoever'

If you can show me a 'type' that cannot be assigned to

a

in the same scope then I would be most interested to know, I haven't
found one yet.

We need to separate out the 'view' from the 'implementation' here.
Most developers I know, if looking at the code and without the possibly
dubious benefit of knowing that in Python 'everything is an object'
would not call this 'strong typing'

Once again, this is not a criticism, it's an observation

It is OK to to make (possibly erroneous) observations isn't it?

Thanks for taking the time to reply.

Mark Lawrence

unread,
Aug 22, 2012, 2:07:52 PM8/22/12
to pytho...@python.org
On 22/08/2012 18:06, lipska the kat wrote:
> On 22/08/12 17:30, Mark Lawrence wrote:
>> On 22/08/2012 17:10, lipska the kat wrote:
>>> On 22/08/12 16:58, MRAB wrote:
>>>> On 22/08/2012 15:59, lipska the kat wrote:
>>>>> On 22/08/12 15:13, shaun wrote:
>>>>>
>>>>> [snip]
>>>>>
>>>>>> Im very new to python and the object orientated feature doesnt seem
>>>>>> to be as well put together as Java. Can anyone help with this
>>>>>> problem?
>
>>>
>>> The residents can be pretty defensive as well :-)
>>>
>>> Once again, no criticism intended.
>>>
>>> lipska
>>>
>>
>> I'm lost. I see nothing defensive at all. I see a statement of fact.
>
>
> You seem to be perpetually lost Mark ...
>
>
> lipska
>

Maybe but I seem to understand Python rather better than some people :)

Once again, no criticism intended.



--
Cheers.

Mark Lawrence.

Ian Kelly

unread,
Aug 22, 2012, 2:15:09 PM8/22/12
to Python
On Wed, Aug 22, 2012 at 11:46 AM, lipska the kat
<lipska...@yahoo.co.uk> wrote:
> If, in a language, I find I am able to say
>
> a = 1
>
> then later, in the same scope I can say
>
> a = "foo"
>
> then later again in the same scope I can say
>
> a = ([1,2,3], "xyz", True)
>
> then, and I may be missing something here, to me, that doesn't say 'strongly
> typed' that says 'no typing constraints whatsoever'

You're conflating "strong typing" with "static typing". Strong typing
does not refer to restrictions on what type of data can be stored
where, but to restrictions on how operations on that data can be
intermixed.

The classic example of weak typing is concatenation of strings and
numbers, e.g. ("abc" + 123). Weakly typed languages like JavaScript
will implicitly coerce the number to a string and perform the
concatenation. Strongly typed languages like Python will raise a
TypeError instead.

Note that statically typed languages can be weakly typed as well. For
instance, C is commonly considered to be weakly typed because the
casting rules of that language allow you to treat any piece of data as
being of any type, even though the variables themselves are all
statically typed.

Mark Lawrence

unread,
Aug 22, 2012, 2:23:44 PM8/22/12
to pytho...@python.org
On 22/08/2012 18:46, lipska the kat wrote:
> On 22/08/12 18:01, Terry Reedy wrote:
>> On 8/22/2012 10:59 AM, lipska the kat wrote:
>>
>>> There is no real enforced concept of information hiding, no binding of
>>> type to variable in fact no concept of typing at all as far as I can
>>> see.
>>
>> Given that type(valid_name) always returns a type(class), that is a
>> slightly strange statement.
>
> [snip]
>
> Well I'm a beginner so I'm allowed to make strange statements.
> However I don't think it's that strange and here's why.
>
> If, in a language, I find I am able to say
>
> a = 1
>
> then later, in the same scope I can say
>
> a = "foo"
>
> then later again in the same scope I can say
>
> a = ([1,2,3], "xyz", True)
>
> then, and I may be missing something here, to me, that doesn't say
> 'strongly typed' that says 'no typing constraints whatsoever'
>
> If you can show me a 'type' that cannot be assigned to
>
> a
>
> in the same scope then I would be most interested to know, I haven't
> found one yet.

You've said nothing above except that any object you like can be bound
to a Python name. The name 'a' is never used. What happens when you
actually do something with the object that you've bound to 'a'?

>
> We need to separate out the 'view' from the 'implementation' here.
> Most developers I know, if looking at the code and without the possibly
> dubious benefit of knowing that in Python 'everything is an object'
> would not call this 'strong typing'

I really despair that after ten years of using Python people still seem
to be incapable of distinguishing strong, static, weak and dynamic
typing. Not that it's a specific Python problem of course, just that I
always get to read about it here.

>
> Once again, this is not a criticism, it's an observation
>
> It is OK to to make (possibly erroneous) observations isn't it?

Not if undoes concepts that computer scientists have patiently been
trying to explain for years.

>
> Thanks for taking the time to reply.
>
> lipska
>


--
Cheers.

Mark Lawrence.

lipska the kat

unread,
Aug 22, 2012, 3:03:16 PM8/22/12
to
On 22/08/12 19:15, Ian Kelly wrote:
> On Wed, Aug 22, 2012 at 11:46 AM, lipska the kat
> <lipska...@yahoo.co.uk> wrote:
>> If, in a language, I find I am able to say
>>
>> a = 1

[snip]

>
> You're conflating "strong typing" with "static typing". Strong typing
> does not refer to restrictions on what type of data can be stored
> where, but to restrictions on how operations on that data can be
> intermixed.

Yes of course I am, thank you for pointing that out.
I don't know why I have this overwhelming need to see variables
explicitly defined ... years of 'same old same old' I suppose.

I do seem to remember reading something about Python moving towards
static typing and there are tools out there to help avoid run time
disasters ... anyway, this has latched now so thanks for taking the time

lipska the kat

unread,
Aug 22, 2012, 3:13:59 PM8/22/12
to
On 22/08/12 19:07, Mark Lawrence wrote:
> On 22/08/2012 18:06, lipska the kat wrote:
>> On 22/08/12 17:30, Mark Lawrence wrote:
>>> On 22/08/2012 17:10, lipska the kat wrote:
>>>> On 22/08/12 16:58, MRAB wrote:
>>>>> On 22/08/2012 15:59, lipska the kat wrote:
>>>>>> On 22/08/12 15:13, shaun wrote:
>>>>>>

[snip]

>
> Maybe but I seem to understand Python rather better than some people :)

Well I should certainly hope so after '10 years of using Python'
I freely admit I don't fully understand Python yet but I will and
hopefully it won't take 10 years ;-)

Never give up, never surrender !!!

> Once again, no criticism intended.

None taken

Evan Driscoll

unread,
Aug 22, 2012, 3:03:30 PM8/22/12
to lipska the kat, pytho...@python.org
On 08/22/2012 12:46 PM, lipska the kat wrote:
> If you can show me a 'type' that cannot be assigned to
>
> a
>
> in the same scope then I would be most interested to know, I haven't
> found one yet.

As other people have said, you've just pointed out the difference
between static typing and dynamic typing -- and how the former types
variables (or "names") and the latter types objects. I just have a few
things to add to your post and others.


First, from some point of view, you're correct. From a type theory point
of view "dynamically typed" is an oxymoron, because *by definition*
(from this point of view) types are a property of variables (and
expressions). For example, Ben Pierce says (in "Types and Programming
Languages"):

The word "static" is sometimes added explicitly...to distinguish
the sorts of compile-time analyses we are considering here from the
dynamic or latent typing found in languages such as Scheme, where
run-time type tags are used to distinguish different kinds of
structures in the heap. Terms like "dynamically typed" are arguably
misnomers and should probably be replaced by "dynamically checked,"
but the usage is standard.

(And the usage is standard because it's just really useful to be able to
say "dynamically-typed" instead of "uni-typed with runtime checks of
things that act like types". (I don't think Pierce's "dynamically
checked" is specific enough. :-))


Second, this concept isn't *so* unfamiliar to you. If I give you the
following Java code:

void foo(Object o) { ... }

and ask what type 'o' is, there are kind of two answers. The first is
that 'o' is an 'Object'. But you can't make an Object -- that's an
abstract class. (IIRC. If it's not then just bear with me; you get the
idea. :-)) So from a strictly static type-theory point of view, 'foo' is
unusable because it takes a type which you can never create. But of
course that's not the case, because in actual Java 'o' has some dynamic
type which is a subclass of 'Object'.

Though I'm sure this statement will be *really* popular with this list
</sarcasm>, if it puts your mind at ease a little, you can imagine that
there are no primitive types and Python names all have type 'Object',
but that you can refer to the functions in an object's dynamic type
without explicitly downcasting. (The analogy isn't perfect.)


On 08/22/2012 01:15 PM, Ian Kelly wrote:
> The classic example of weak typing is concatenation of strings and
> numbers, e.g. ("abc" + 123). Weakly typed languages like JavaScript
> will implicitly coerce the number to a string and perform the
> concatenation. Strongly typed languages like Python will raise a
> TypeError instead.

I would also say don't get *too* caught up in categorizing everything
into "strong" and "weak"; that's a spectrum, and where things fall is a
lot more interesting than just "here or there". Really it's even more
complex than just a linear spectrum -- Language A can be stronger than
Language B in one respect but weaker in another.

In particular, it's possible to have rather stronger typing than Python
(especially with respect to Booleans, but in some other respects as well).

Evan

signature.asc

lipska the kat

unread,
Aug 22, 2012, 3:45:44 PM8/22/12
to
On 22/08/12 20:03, Evan Driscoll wrote:
> On 08/22/2012 12:46 PM, lipska the kat wrote:
>> If you can show me a 'type' that cannot be assigned to
>>
>> a
>>
>> in the same scope then I would be most interested to know, I haven't
>> found one yet.
>
[snip]

>
> Second, this concept isn't *so* unfamiliar to you. If I give you the
> following Java code:
>
> void foo(Object o) { ... }
>
> and ask what type 'o' is, there are kind of two answers. The first is
> that 'o' is an 'Object'. But you can't make an Object -- that's an
> abstract class. (IIRC. If it's not then just bear with me; you get the
> idea. :-)) So from a strictly static type-theory point of view, 'foo' is
> unusable because it takes a type which you can never create. But of
> course that's not the case, because in actual Java 'o' has some dynamic
> type which is a subclass of 'Object'.

Well I think this is where I'm struggling a bit.

looking at this method declaration I can see that the method takes an
argument of type Object (and just FYI class Object is not abstract and
you can do Object o = new Object()) and does not return a value.
I know that for the lifetime of this JVM, whatever o turns out to be it
will always be an Object. I can't assign a primitive to o as ints chars
floats etc are certainly not Objects. There are certain invariants that
give me a warm and comfortable feeling inside.

compare this to a function declaration in Python

def foo(self):

... I can learn nothing about this function by looking at the first line

If I see

def foo(self, someVar=1):

I can determine that foo takes an argument that, at some time or other
is or has been a number of some description but I can't rely on it and I
have no idea what is returned and that's where I think I'm having trouble.

But I will get over it and I will learn the language and I may look back
on these exchanges and say ... I was wrong, this is so much better that
what I was used to, or maybe I won't. I'll let you know

Thank you for your calm and reasoned response.

Disclaimer:
None of my comments above should be construed as criticisms
they are just observations.

MRAB

unread,
Aug 22, 2012, 4:31:51 PM8/22/12
to pytho...@python.org
[snip]
That's not actually a declaration but a definition. :-)

The function's body is bound to the name at runtime, so:

def double_it(x):
return x * 2

is not far from:

double_it = lambda x: x * 2

The only declarations are "global" and "nonlocal" (and the latter
exists only in recent versions of Python).

Mark Lawrence

unread,
Aug 22, 2012, 4:46:29 PM8/22/12
to pytho...@python.org
On 22/08/2012 21:31, MRAB wrote:
> On 22/08/2012 20:45, lipska the kat wrote:
>>
>> compare this to a function declaration in Python
>>
>> def foo(self):
>>
> [snip]
> That's not actually a declaration but a definition. :-)
>
> The function's body is bound to the name at runtime, so:
>
> def double_it(x):
> return x * 2
>
> is not far from:
>
> double_it = lambda x: x * 2
>
> The only declarations are "global" and "nonlocal" (and the latter
> exists only in recent versions of Python).

Looking at the self I'm assuming that's a method and not a function.

--
Cheers.

Mark Lawrence.

Evan Driscoll

unread,
Aug 22, 2012, 5:31:08 PM8/22/12
to lipska the kat, pytho...@python.org
On 08/22/2012 02:45 PM, lipska the kat wrote:
> On 22/08/12 20:03, Evan Driscoll wrote:
>> Second, this concept isn't *so* unfamiliar to you. If I give you the
>> following Java code:
>>
>> void foo(Object o) { ... }
>>
> looking at this method declaration I can see that the method takes an
> argument of type Object (and just FYI class Object is not abstract and
> you can do Object o = new Object()) and does not return a value.
> I know that for the lifetime of this JVM, whatever o turns out to be it
> will always be an Object. I can't assign a primitive to o as ints chars
> floats etc are certainly not Objects. There are certain invariants that
> give me a warm and comfortable feeling inside.

I'm not saying it's nothing, but "can't assign a primitive" isn't much
of an invariant in the broad scheme of things when you can pass items as
diverse as lists, GUI buttons, files, etc. I would say it's more like if
you see 'int x' then *that* imposes a pretty big invariant, but passing
'Object' imposes almost nothing.

This is especially true considering the fact that you actually *can* say
'foo(4)' and Java will go and autobox the 4 into Integer(4) for you.

(BTW, this analogy suggests a way that's actually fairly useful for how
to look at Python coming from the Java perspective: Python just lacks
primitive types and things like integers are always boxed. Thus *all*
Python variables are essentially references.)

Evan

signature.asc

Ben Finney

unread,
Aug 22, 2012, 7:58:39 PM8/22/12
to
lipska the kat <lipska...@yahoo.co.uk> writes:

> If, in a language, I find I am able to say
>
> a = 1
>
> then later, in the same scope I can say
>
> a = "foo"
>
> then later again in the same scope I can say
>
> a = ([1,2,3], "xyz", True)
>
> then, and I may be missing something here, to me, that doesn't say
> strongly typed' that says 'no typing constraints whatsoever'

You haven't discovered anything about types; what you have discovered is
that Python name bindings are not variables.

In fact, Python doesn't have variables – not as C or Java programmers
would understand the term. What it has instead are references to objects
(with names as one kind of reference).

The documentation unfortunately calls these references “variables” in
various places, which IMO compounds the confusion in newcomers
experienced with other languages. It's best, I think, to reject the idea
that Python has variables, and think in terms of references instead.

Any reference (with some very narrow specific exclusions, like ‘None’)
can be re-bound to any other object without regard to the previous
binding.

> We need to separate out the 'view' from the 'implementation' here.
> Most developers I know, if looking at the code and without the
> possibly dubious benefit of knowing that in Python 'everything is an
> object' would not call this 'strong typing'

Those people are confused, then. Python is strongly typed: objects
always know their type, the type is always exact, and the type of an
object can't be changed.

This is always true regardless of whether the object is referred to
zero, one, or many times.

Python is dynamically typed: References (and hence names) don't have
types.

> It is OK to to make (possibly erroneous) observations isn't it?

One of our long-time regulars (Aahz, whom I haven't seen for a long
time, sadly) quipped that the best way to get correct information on
Usenet is not to ask a question, but to post incorrect information.
That's not a license for such behaviour, but an observation on its
effectiveness.

I'd say that so long as you phrase your assertions to indicate the level
of confidence and possibility of error, that's okay.

--
\ “Generally speaking, the errors in religion are dangerous; |
`\ those in philosophy only ridiculous.” —David Hume, _A Treatise |
_o__) of Human Nature_, 1739 |
Ben Finney

Ian Kelly

unread,
Aug 22, 2012, 8:10:08 PM8/22/12
to Python
On Wed, Aug 22, 2012 at 5:58 PM, Ben Finney <ben+p...@benfinney.id.au> wrote:
> Those people are confused, then. Python is strongly typed: objects
> always know their type, the type is always exact, and the type of an
> object can't be changed.

Except when it can.

>>> class A: pass
...
>>> class B: pass
...
>>> a = A()
>>> type(a)
<class '__main__.A'>
>>> isinstance(a, B)
False
>>> a.__class__ = B
>>> type(a)
<class '__main__.B'>
>>> isinstance(a, A)
False
>>> isinstance(a, B)
True

Cheers,
Ian

Walter Hurry

unread,
Aug 22, 2012, 9:19:49 PM8/22/12
to
On Wed, 22 Aug 2012 18:46:43 +0100, lipska the kat wrote:

> Well I'm a beginner

Then maybe you should read more and write less.

Chris Angelico

unread,
Aug 22, 2012, 10:02:16 PM8/22/12
to pytho...@python.org
On Thu, Aug 23, 2012 at 5:03 AM, lipska the kat
<lipska...@yahoo.co.uk> wrote:
> On 22/08/12 19:15, Ian Kelly wrote:
>>
>> You're conflating "strong typing" with "static typing". Strong typing
>> does not refer to restrictions on what type of data can be stored
>> where, but to restrictions on how operations on that data can be
>> intermixed.
>
> Yes of course I am, thank you for pointing that out.
> I don't know why I have this overwhelming need to see variables explicitly
> defined ... years of 'same old same old' I suppose.

Python's object model is not fundamentally incompatible with a system
of declared variables. I, too, like declaring my variables explicitly.
There are quite a few advantages to it:

1) Scoping is extremely clear. (Leaving aside anomalous behaviour like
Javascript's "var" declarations applying to a whole function.) You see
a declaration, you know that variable exists there and further inside
only. In a C-style language, that means it disappears at the
corresponding close brace.

2) Related to the above, you can infinitely nest scopes. There's
nothing wrong with having six variables called 'q'; you always use the
innermost one. Yes, this can hurt readability, especially taken to
this sort of stupid extreme, but that's a question for a style guide
and not a language design.

3) Variable-name typos can be caught at parse time. In Python, if you
misspell a variable, you've just made a new local variable.

It has its downsides, too, of course; mainly that it's (in some
people's opinion) syntactic salt. Why should I have to tell the
interpreter/compiler what it can figure out by itself? It's
duplicating information, and that's inefficient. It's like forcing all
your integer constants to be given in both decimal and hex, to catch
errors.

I'm of the opinion that the benefits are worth the effort. Others
disagree. It's hugely a matter of taste, and I'm just glad that there
are enough languages around that we can all have what we want :)

If you like the Python object model but want to add variable
declarations, grab me off list and I'll tell you about my personal
favorite language...

ChrisA

Steven D'Aprano

unread,
Aug 23, 2012, 12:07:00 AM8/23/12
to
On Wed, 22 Aug 2012 21:46:29 +0100, Mark Lawrence wrote:

>> On 22/08/2012 20:45, lipska the kat wrote:
>>>
>>> compare this to a function declaration in Python
>>>
>>> def foo(self):
[...]
> Looking at the self I'm assuming that's a method and not a function.


Actually, it is a function. It doesn't get turned into a method until you
try to use it.

The way methods work in Python is this:

Function objects are created by the "def" statement, regardless of
whether that is inside a class or not. So:

class X(object):
def spam(self, value):
pass

creates a single function object which takes one argument, self, and
sticks in in the class namespace X.__dict__['spam'] = spam

When you look up the name "spam" on an X instance:

x = X()
x.spam(42)

Python does it's usual attribute lookup stuff, finds the name "spam" in
the class namespace, and extracts the function object. So far that's just
ordinary attribute access. This is where it gets interesting...

Function objects are *descriptors*, which means that they have a __get__
method:

py> (lambda x: None).__get__
<method-wrapper '__get__' of function object at 0xb71bd77c>

Python sees that __get__ method and calls it with some appropriate
arguments (the class object and the instance object, I believe) and the
__get__ method constructs a method on the fly, handles the automatic bind-
instance-to-self magic, and returns the method object. And then finally
Python calls the method object with whatever arguments you provided.

As they say, "You can solve any problem in computer science with
sufficient layers of indirection". This descriptor protocol, as they call
it, is the mechanism behind methods, class methods, static methods,
properties, and probably other things as well.

You can do all sorts of funky things with descriptors -- google for
"descriptor protocol", "data descriptor", "non-data descriptor" etc. if
you are interested. Here's a trivial, but useful, one:

http://code.activestate.com/recipes/577030-dualmethod-descriptor/


--
Steven

Steven D'Aprano

unread,
Aug 23, 2012, 12:11:52 AM8/23/12
to
On Thu, 23 Aug 2012 12:02:16 +1000, Chris Angelico wrote:

> 2) Related to the above, you can infinitely nest scopes. There's nothing
> wrong with having six variables called 'q'; you always use the innermost
> one. Yes, this can hurt readability

Well, there you go. There *is* something wrong with having six variables
called 'q'.

Namespaces and scopes are work-arounds for the fact that, while there are
an infinite number of possible names, most of the good ones are already
taken.

Namespaces and scopes mean that I can use a name "q" even though I've
already used it for something else, but there is still cost to re-using
names (even if that cost is sometimes trivial).


--
Steven

Steven D'Aprano

unread,
Aug 23, 2012, 12:14:55 AM8/23/12
to
I think that's uncalled for. Lipska isn't trolling. He's making
observations as he sees them. The fact that they're sometimes wrong is
not a reason to effectively tell him to STFU.

Better the misconception which is spoken allowed and corrected, then the
one which is kept quiet and festers.

--
Steven

Steven D'Aprano

unread,
Aug 23, 2012, 12:34:52 AM8/23/12
to
On Wed, 22 Aug 2012 18:46:43 +0100, lipska the kat wrote:

> We need to separate out the 'view' from the 'implementation' here. Most
> developers I know, if looking at the code and without the possibly
> dubious benefit of knowing that in Python 'everything is an object'
> would not call this 'strong typing'

Most developers are wrong :)

A very useful resource to read is "What To Know Before Debating Type
Systems", which was put on the internet, lost, then found and put back up
here:

http://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wrote/

I don't *quite* go so far as to agree that "strong typing" and "weak
typing" are meaningless, but they certainly don't mean quite as much as
people sometimes think.

It also includes this brilliant quote:

"I find it amusing when novice programmers believe their main job is
preventing programs from crashing. ... More experienced programmers
realize that correct code is great, code that crashes could use
improvement, but incorrect code that doesn’t crash is a horrible
nightmare."

In Python's case, we say:

1) objects are strongly typed -- every object has a type, which is
usually immutable and sometimes known at compile time;

2) names (what some people insist on calling variables) are not typed at
all (with the exception of a handful of keywords like None);

3) most Python built-ins are strongly typed, and users are discouraged
from writing excessively weakly-typed operations (you could write an int
subclass that can be added to a string or a list, just as you can add it
to a float, but you shouldn't);

4) there's a culture of preferring "duck typing", which is kind of an ad
hoc form of interfaces, over strict type testing, so users are also
discouraged from writing excessively strongly-typed operations (if you
just need something you can iterate over, why insist that it must be a
list and nothing but a list?).


--
Steven

Evan Driscoll

unread,
Aug 23, 2012, 12:49:17 AM8/23/12
to Ben Finney, pytho...@python.org
On 8/22/2012 18:58, Ben Finney wrote:
> You haven't discovered anything about types; what you have discovered is
> that Python name bindings are not variables.
>
> In fact, Python doesn't have variables – not as C or Java programmers
> would understand the term. What it has instead are references to objects
> (with names as one kind of reference).

OK, I've seen this said a few times, and I have to ask: what do you mean
by this? I consider myself pretty decent at Python and other languages,
and I really don't get it.

Especially the comparison to Java variables. Java programmers are quite
used to variables which are references to objects: everything that's not
a primitive type is a reference, and it's kinda hard to determine
whether primitives are references or actual primitives.

And many other languages have reference behavior and still call their
bindings "variables", e.g. Scheme.

Evan


signature.asc

Chris Angelico

unread,
Aug 23, 2012, 1:26:10 AM8/23/12
to pytho...@python.org
On Thu, Aug 23, 2012 at 2:11 PM, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
> On Thu, 23 Aug 2012 12:02:16 +1000, Chris Angelico wrote:
>
>> 2) Related to the above, you can infinitely nest scopes. There's nothing
>> wrong with having six variables called 'q'; you always use the innermost
>> one. Yes, this can hurt readability
>
> Well, there you go. There *is* something wrong with having six variables
> called 'q'.

But it's the same thing that's wrong with having one variable called
'q', when that variable would be better called 'invoice' because it's
iterating over your invoices, or 'item' when it's iterating over the
lines of one invoice. Python doesn't stop you from doing that; it's
not the language's job to enforce useful variable names.

ChrisA

Chris Angelico

unread,
Aug 23, 2012, 1:33:33 AM8/23/12
to pytho...@python.org
On Thu, Aug 23, 2012 at 2:49 PM, Evan Driscoll <dris...@cs.wisc.edu> wrote:
> On 8/22/2012 18:58, Ben Finney wrote:
>> You haven't discovered anything about types; what you have discovered is
>> that Python name bindings are not variables.
>>
>> In fact, Python doesn't have variables – not as C or Java programmers
>> would understand the term. What it has instead are references to objects
>> (with names as one kind of reference).
>
> OK, I've seen this said a few times, and I have to ask: what do you mean
> by this? I consider myself pretty decent at Python and other languages,
> and I really don't get it.

Simple example that'll work in many languages:

x = 1;

In C, this means: Assign the integer 1 to the variable x (possibly
with implicit type casting, eg to floating point).

In Java or C++, this means: Assign the integer 1 to the variable x.
Ditto, but possibly 'x' is actually a class member etc rather than a
simple variable.

In Python, this means: Make the name x now refer to the object 1.
Whatever x had before is de-referenced by one (in a simple refcounting
situation, that may result in the object being destroyed), and the
object referred to by the literal 1 is now pointed to by x.

Names are just one kind of reference because complex objects can have
unnamed references. For instance:

foo = [1, 2, 3]
foo[1] = "Hello, world!"

The second element of foo just got rebound in exactly the same way x
did, but it doesn't have a name of its own.

Does that sort things out, or just make things more confusing?

ChrisA

Steven D'Aprano

unread,
Aug 23, 2012, 2:55:33 AM8/23/12
to
On Wed, 22 Aug 2012 23:49:17 -0500, Evan Driscoll wrote:

> On 8/22/2012 18:58, Ben Finney wrote:
>> You haven't discovered anything about types; what you have discovered
>> is that Python name bindings are not variables.
>>
>> In fact, Python doesn't have variables – not as C or Java programmers
>> would understand the term. What it has instead are references to
>> objects (with names as one kind of reference).
>
> OK, I've seen this said a few times, and I have to ask: what do you mean
> by this? I consider myself pretty decent at Python and other languages,
> and I really don't get it.

I think the point that Ben would like to make is that while "name
binding" is a specific kind of "variable", the word "variable" comes with
too much baggage from the old-school C, Pascal etc. style of variables-
are-named-memory-locations. Most of the time, the differences are
unimportant, but when they are important, if your mental image is that
Python "variables" (name bindings) are like C or Pascal
"variables" (memory locations), you're going to get confused.


[...]
> And many other languages have reference behavior and still call their
> bindings "variables", e.g. Scheme.

Yes, well in my opinion, a great deal of the terminology in use is
absolutely dire. E.g. both Ruby and Java have the exact same parameter
binding strategy as Python, only the Ruby people call theirs "call by
reference" and the Java people call theirs "call by value", *both of
which are identical*, and NEITHER of which are the same thing that C and
Pascal programmers will understand by call by value *or* call by
reference.

http://mail.python.org/pipermail/tutor/2010-December/080505.html



--
Steven

lipska the kat

unread,
Aug 23, 2012, 4:03:19 AM8/23/12
to
Really ? I read all the responses to my posts and learn more from them
in less time than I ever have from reading the 'documentation'

If you don't like it then don't read it.

lipska the kat

unread,
Aug 23, 2012, 4:10:55 AM8/23/12
to
Excellent advice as usual, but I'm more than capable of looking after
myself thank you.

Nobody has ever succeeded in making me STFU yet :-)

When that day comes I'll retire to the garden

Jussi Piitulainen

unread,
Aug 23, 2012, 4:59:56 AM8/23/12
to
Steven D'Aprano writes:
> On Wed, 22 Aug 2012 23:49:17 -0500, Evan Driscoll wrote:
>
> > On 8/22/2012 18:58, Ben Finney wrote:
> >> You haven't discovered anything about types; what you have
> >> discovered is that Python name bindings are not variables.
> >>
> >> In fact, Python doesn't have variables – not as C or Java
> >> programmers would understand the term. What it has instead are
> >> references to objects (with names as one kind of reference).
> >
> > OK, I've seen this said a few times, and I have to ask: what do
> > you mean by this? I consider myself pretty decent at Python and
> > other languages, and I really don't get it.
>
> I think the point that Ben would like to make is that while "name
> binding" is a specific kind of "variable", the word "variable" comes
> with too much baggage from the old-school C, Pascal etc. style of
> variables- are-named-memory-locations. Most of the time, the
> differences are unimportant, but when they are important, if your
> mental image is that Python "variables" (name bindings) are like C
> or Pascal "variables" (memory locations), you're going to get
> confused.

I don't get it either. To me the python-has-no-variables campaigners
seem confused. As far as I can see, Python can be seen in terms of
variables bound to (locations containing) values perfectly well, in a
way that should be quite familiar to people who come from Java (or
Lisp, Scheme like me).

It is very bad that people campaign here against the terminology that
is used in the official Python language reference and the Python
tutorial.

Best would be to simply explain how the variables, values, assignment,
and calls work in Python, the way the language reference and tutorial
actually do.

If the no-variables campaign is to continue, the language reference
and the tutorial should be changed to match. I would consider it a mad
move, but the current practice of badmouthing the official wording is
not healthy either.

> [...]
> > And many other languages have reference behavior and still call
> > their bindings "variables", e.g. Scheme.
>
> Yes, well in my opinion, a great deal of the terminology in use is
> absolutely dire. E.g. both Ruby and Java have the exact same
> parameter binding strategy as Python, only the Ruby people call
> theirs "call by reference" and the Java people call theirs "call by
> value", *both of which are identical*, and NEITHER of which are the
> same thing that C and Pascal programmers will understand by call by
> value *or* call by reference.

That's indeed such a mess that those call-by-* terms may be now best
avoided. I would also avoid any distinction between an object and a
"reference" to an object, except as an implementation detail. It's not
helpful. It only leads to the confusion where it seems that Java (or
Python) does not actually have objects at all, only references to
objects, which in turn don't exist, so, er, what.

The swap function is helpful. Why doesn't it work? Because it assigns
to different variables that are local to the function. If I pass it a
list, why can it then swap the elements? Because that is the same
list, not a copy. Get used to it. Works for me.

lipska the kat

unread,
Aug 23, 2012, 5:19:36 AM8/23/12
to
On 22/08/12 22:31, Evan Driscoll wrote:
> On 08/22/2012 02:45 PM, lipska the kat wrote:
>> On 22/08/12 20:03, Evan Driscoll wrote:
>>> Second, this concept isn't *so* unfamiliar to you. If I give you the
>>> following Java code:
>>>
>>> void foo(Object o) { ... }
>>>
>> looking at this method declaration I can see that the method takes an
>> argument of type Object (and just FYI class Object is not abstract and
>> you can do Object o = new Object()) and does not return a value.
>> I know that for the lifetime of this JVM, whatever o turns out to be it
>> will always be an Object. I can't assign a primitive to o as ints chars
>> floats etc are certainly not Objects. There are certain invariants that
>> give me a warm and comfortable feeling inside.
>
> I'm not saying it's nothing, but "can't assign a primitive" isn't much
> of an invariant in the broad scheme of things

Well we don't want to turn this into a language comparison thread do we,
that might upset too many people but I can't remember ever writing a
method that took an Object as argument, you just can't do that much with
an Object. I do however often write methods that take an interface as
argument knowing that in future, any classes I write that implement this
interface would just work thanks to subtype polymorphism

A method 'declaration' such as this in an interface

Product getProductByBarcode(Barcode b) throws CrappyProductException;

tells me a whole lot about what the 'definition' in an implementing
class might do, in fact I might well get away with just reading the
interface and using the method without having to delve into the code.

And I think this is the nub of the problem at the moment. I'm in a
particular mindset, almost 'locked in' you might say and when I see a
Python function that doesn't give me what I need straight away I get
annoyed.

I will get over it.

> when you can pass items as
> diverse as lists, GUI buttons, files, etc. I would say it's more like if
> you see 'int x' then *that* imposes a pretty big invariant, but passing
> 'Object' imposes almost nothing.

Well you may be able to pass them in but you couldn't really do anything
meaningful with them as you are restricted to operations on Object, I
suppose you could pepper your code with tests to check the runtime type
of a reference but it all gets a bit messy.

[snip]

> Thus *all*
> Python variables are essentially references.)

That makes sense

Thanks for taking the time to reply. It really is most valuable to me.

MRAB

unread,
Aug 23, 2012, 7:28:55 AM8/23/12
to pytho...@python.org
[snip]
In Java a variable exists even when it has not been assigned a value.
In Python, on the other hand, the basic model is that a 'variable'
doesn't exist until it has been bound to an value (although, for
efficiency reasons, that's not entirely true, because at compile time
CPython will identify the local variables in a function and allocate a
'slot' for it).

Ben Finney

unread,
Aug 23, 2012, 9:59:47 AM8/23/12
to
lipska the kat <lipska...@yahoo.co.uk> writes:

> On 23/08/12 05:14, Steven D'Aprano wrote:
> > I think that's uncalled for.
[…]

> Excellent advice as usual, but I'm more than capable of looking after
> myself thank you.

As is usual, it's not all about you; Steven is demonstrating that we
require civil behaviour here, for anyone who may be watching but not
saying anything.

--
\ “Skepticism is the highest duty and blind faith the one |
`\ unpardonable sin.” —Thomas Henry Huxley, _Essays on |
_o__) Controversial Questions_, 1889 |
Ben Finney

Ben Finney

unread,
Aug 23, 2012, 10:16:49 AM8/23/12
to
Evan Driscoll <dris...@cs.wisc.edu> writes:

> Especially the comparison to Java variables. Java programmers are
> quite used to variables which are references to objects: everything
> that's not a primitive type is a reference, and it's kinda hard to
> determine whether primitives are references or actual primitives.
>
> And many other languages have reference behavior and still call their
> bindings "variables", e.g. Scheme.

In these languages, programmers are presented with a data model that
emulates storage locations. A variable refers to a location, and
changing to a different object doesn't change the nominal location.

In Python, though, there is no such concept. A reference binds directly
to an object. If anything can be called a “variable”, it is the binding;
but the binding has no name and has no type, and there's nothing the
programmer can do with it except delete it. So it bears very little
useful connection with what most programmers will think of the term
“variable”.

--
\ “I don't accept the currently fashionable assertion that any |
`\ view is automatically as worthy of respect as any equal and |
_o__) opposite view.” —Douglas Adams |
Ben Finney

lipska the kat

unread,
Aug 23, 2012, 10:20:29 AM8/23/12
to
On 23/08/12 14:59, Ben Finney wrote:
> lipska the kat<lipska...@yahoo.co.uk> writes:
>
>> On 23/08/12 05:14, Steven D'Aprano wrote:
>>> I think that's uncalled for.
> […]
>
>> Excellent advice as usual, but I'm more than capable of looking after
>> myself thank you.
>
> As is usual, it's not all about you; Steven is demonstrating that we
> require civil behaviour here, for anyone who may be watching but not
> saying anything.

You 'require civil behaviour here' do you. Well so far I have been very
civil.

This is a USENET newsgroup, it's a public forum, not your personal
domain. Please stop all this 'it's not all about you' meaningless
nonsense. It's pointless and wastes mine and no doubt others time.

If you want to carry this on please contact me off list.

Ben Finney

unread,
Aug 23, 2012, 10:24:49 AM8/23/12
to
lipska the kat <lipska...@yahoo.co.uk> writes:

> On 23/08/12 14:59, Ben Finney wrote:
> > lipska the kat<lipska...@yahoo.co.uk> writes:
> >
> >> On 23/08/12 05:14, Steven D'Aprano wrote:
> >>> I think that's uncalled for.
> > […]
> >
> >> Excellent advice as usual, but I'm more than capable of looking after
> >> myself thank you.
> >
> > As is usual, it's not all about you; Steven is demonstrating that we
> > require civil behaviour here, for anyone who may be watching but not
> > saying anything.
>
> You 'require civil behaviour here' do you. Well so far I have been
> very civil.

And I say again: it's not all about you. Steven's respons was to a
different person in this thread. Please stop reacting as if everything
said around you is directed at you.

Jerry Hill

unread,
Aug 23, 2012, 10:43:48 AM8/23/12
to pytho...@python.org
On Thu, Aug 23, 2012 at 4:59 AM, Jussi Piitulainen
<jpii...@ling.helsinki.fi> wrote:
> I don't get it either. To me the python-has-no-variables campaigners
> seem confused. As far as I can see, Python can be seen in terms of
> variables bound to (locations containing) values perfectly well, in a
> way that should be quite familiar to people who come from Java (or
> Lisp, Scheme like me).

Personally, when I was learning python I found the idea of python
having names and values (rather than variables and references) to
clear up a lot of my misconceptions of the python object model. I
think it's done the same for other people too, especially those who
come from the C world, where a variable is a named and typed location
in memory.

Perhaps those that come from the Java and Lisp world don't find the
name/value paradigm as helpful. Still, it seems silly to excoriate
people on the list for trying to explain python fundamentals in
several different ways. Sometimes explaining the same idea in
different words helps people understand the concept better.

--
Jerry

Evan Driscoll

unread,
Aug 23, 2012, 12:44:01 PM8/23/12
to lipska the kat, pytho...@python.org
On 08/23/2012 04:19 AM, lipska the kat wrote:
> Well we don't want to turn this into a language comparison thread do we,
> that might upset too many people but I can't remember ever writing a
> method that took an Object as argument, you just can't do that much with
> an Object.

In the pre-Java-1.5 days, functions that took Objects were *very*
common; e.g. every collections class. Even now there are probably
lingering cases where either there's some code that hasn't been
genericized or is too much work to genericize to make it worthwhile. (I
do very little Java programming so can't point to any concrete cases if
you would (reasonably) reject the example of java.util.collections being
used in their non-generic form.)

Anyway, the point wasn't that 'foo(Object o)' is common, just that
you've probably seen something which is somewhat comparable.

Evan


signature.asc

rusi

unread,
Aug 23, 2012, 1:04:51 PM8/23/12
to
On Aug 23, 9:34 am, Steven D'Aprano <steve
+comp.lang.pyt...@pearwood.info> wrote:
> On Wed, 22 Aug 2012 18:46:43 +0100, lipska the kat wrote:
> > We need to separate out the 'view' from the 'implementation' here. Most
> > developers I know, if looking at the code and without the possibly
> > dubious benefit of knowing that in Python 'everything is an object'
> > would not call this 'strong typing'
>
> Most developers are wrong :)
>
> A very useful resource to read is "What To Know Before Debating Type
> Systems", which was put on the internet, lost, then found and put back up
> here:
>
> http://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wrote/

Thanks for that article.
There was one by Peter Wegner -- exact one I cant find. Here's a good
approximation:
http://analysis-of-persistence-tools.googlecode.com/files/p7-wegner.pdf

Section 5.2.1 in particular has 7 different things that the word
'type' could mean to different types(!) of programmers.

Evan Driscoll

unread,
Aug 23, 2012, 1:17:03 PM8/23/12
to pytho...@python.org
[I have some things to say to a few people so I'm just putting it all in
one rather than clutter up your email box even more.]

On 08/23/2012 12:33 AM, Chris Angelico wrote:
> [Snip discussion on names vs variables]
>
> Does that sort things out, or just make things more confusing?
>
> ChrisA

I... am not sure. I don't think it really told me anything new. I think
it's just that I don't think that any of the distinctions (nor all of
them put together) makes it worthwhile to reject a perfectly good term
in common use just because the behavior of Python variables is a bit
different from the behavior of variables in *some* other languages.

For instance, I don't get annoyed that both Java and Python use the
terms "class" and "object" for similar but still very different things.
And while I think it's worth saying "Python classes and objects are
rather different from Java's", I definitely *wouldn't* say "Python
classes aren't really classes" -- even though (I assert) Python classes
are *far* further from Simula-style (/Java/C++) classes than Python
variables are from Java variables.


On 08/23/2012 03:59 AM, Jussi Piitulainen wrote:
> I would also avoid any distinction between an object and a
> "reference" to an object, except as an implementation detail. It's not
> helpful.

Whaaaa....?

How would you describe it then? To me, that distinction is absolutely
*fundamental* to understanding how languages like Python/Scheme/Java
work, because it tells you how to reason about aliasing behavior in an
unconvoluted way (which is essential to understanding how they work).

How would *you* suggest dealing with that issue?


On 08/23/2012 09:43 AM, Jerry Hill wrote:
> On Thu, Aug 23, 2012 at 4:59 AM, Jussi Piitulainen wrote:
>> I don't get it either. To me the python-has-no-variables campaigners
>> seem confused. As far as I can see, Python can be seen in terms of
>> variables bound to (locations containing) values perfectly well, in a
>> way that should be quite familiar to people who come from Java (or
>> Lisp, Scheme like me).
>
> ...
>
> Perhaps those that come from the Java and Lisp world don't find the
> name/value paradigm as helpful. Still, it seems silly to excoriate
> people on the list for trying to explain python fundamentals in
> several different ways. Sometimes explaining the same idea in
> different words helps people understand the concept better.

I agree with this, and I'm happy that people found it useful.

*However*, this thread wasn't really prompted by someone just trying to
explain variables in different terms -- it was prompted by one of the
many comments you see from time-to-time that "Python doesn't have
variables – not as C or Java programmers would understand the term".
That's a different than saying "here's another way of looking at Python
variables", and that instance is even toned down compared to a lot of
the instances you'll find (which will often omit the qualification at
the end).

To me, saying "here's an alternative way to look at variables" is great,
but saying "Python doesn't have variables" is, IMO, at least as silly as
what Jussi said. To me, dancing around the issue just leads to more
confusing terminology and makes things worse.

(And this is reinforced by the fact that neither I nor Google seems to
have really seen "Python doesn't have classes" ever used, when that
statement is at least as true as "Python doesn't have variables".)

Evan

signature.asc

Terry Reedy

unread,
Aug 23, 2012, 1:17:38 PM8/23/12
to pytho...@python.org
On 8/23/2012 10:43 AM, Jerry Hill wrote:

> Personally, when I was learning python I found the idea of python
> having names and values (rather than variables and references) to
> clear up a lot of my misconceptions of the python object model. I
> think it's done the same for other people too, especially those who
> come from the C world, where a variable is a named and typed location
> in memory.

There are two important points about C and assembler. First, the named
locations (and un-named internal locations like function return
addresses) are *contiguous*. Giving a user access to one block may give
a user access to other blocks if one is not careful. The other is that
the typing is in the code and compiler, but not in the runtime memory.
So text input can be read as code and a return jump address to the bytes
interpreted as code.

--
Terry Jan Reedy

Steven D'Aprano

unread,
Aug 23, 2012, 1:56:25 PM8/23/12
to
On Thu, 23 Aug 2012 12:17:03 -0500, Evan Driscoll wrote:

> I definitely *wouldn't* say "Python
> classes aren't really classes" -- even though (I assert) Python classes
> are *far* further from Simula-style (/Java/C++) classes than Python
> variables are from Java variables.

Well, Python classes are first-class (pun not intended) objects in their
own right, and hence are data. Java and C++ classes are not, they are
instructions to the compiler rather than data.

But other than that, what do you see as the difference between Python
classes and Simula-style classes?



> On 08/23/2012 03:59 AM, Jussi Piitulainen wrote:
>> I would also avoid any distinction between an object and a "reference"
>> to an object, except as an implementation detail. It's not helpful.
>
> Whaaaa....?
>
> How would you describe it then? To me, that distinction is absolutely
> *fundamental* to understanding how languages like Python/Scheme/Java
> work, because it tells you how to reason about aliasing behavior in an
> unconvoluted way (which is essential to understanding how they work).
>
> How would *you* suggest dealing with that issue?

Given:

x = some_object()
y = x

I could say that x and y are the same object, rather than x and y are
references to the same object.

Sometimes, when I say "x", I mean the *name* x, which is a reference to
some object.

Much more often though, when I say "x", I use it as a convenient label
for some object. Rather than saying "the object which is referenced to by
the name x", I just say "x".

Nearly always, the meaning is obvious in context.


[...]
> *However*, this thread wasn't really prompted by someone just trying to
> explain variables in different terms -- it was prompted by one of the
> many comments you see from time-to-time that "Python doesn't have
> variables – not as C or Java programmers would understand the term".

No offence to Ben Finney, but I think sometimes he's a bit too eager to
emphasise the subtle differences between Python and other languages,
rather than the similarities. (I used to be like Ben in this regard, but
I got better -- or worse, depending on your perspective.)

Again, context is important: sometimes I will choose to gloss over the
differences by calling x a variable, and sometimes I will emphasise the
differences to C or Pascal by referring to name binding.


> To me, saying "here's an alternative way to look at variables" is great,
> but saying "Python doesn't have variables" is, IMO, at least as silly as
> what Jussi said. To me, dancing around the issue just leads to more
> confusing terminology and makes things worse.
>
> (And this is reinforced by the fact that neither I nor Google seems to
> have really seen "Python doesn't have classes" ever used, when that
> statement is at least as true as "Python doesn't have variables".)

I think you are utterly wrong here.

Python has classes. They are created by the "class" keyword. Whether
those classes are identical to Java classes is irrelevant -- in Python,
these whatever-they-are-things are called "classes", and so Python has
classes.

But Python does not have things called "variables". There is no
"variable" keyword to create a variable. It is absolutely fundamental to
the programming model of Python that it has objects which are bound to
names in namespaces (and other entities, such as list items). That is
*critical* -- Python uses name bindings.

But name bindings are a kind of variable. Named memory locations are a
*different* kind of variable. The behaviour of C variables and Python
variables do not follow the Liskov Substitution Principle -- you can't
rip out the entire "names bound to objects" machinery of Python and
replace it with C-like named memory locations without changing the high-
level behaviour of Python. And so by some ways of thinking it is *wrong*
to treat name bindings and memory locations as "the same sort of entity".
Hence, if C variables are variables, then Python name bindings can't be.

I used to agree with that reasoning. I no longer do, not entirely. While
I see the differences between them -- for instance, C variables exist
before they have a value assigned to them, Python name bindings do not --
I don't think the differences are important enough to *prohibit* use of
the word "variable" to describe name bindings. Only to discourage it.



--
Steven

lipska the kat

unread,
Aug 23, 2012, 1:56:58 PM8/23/12
to
On 23/08/12 17:44, Evan Driscoll wrote:
> On 08/23/2012 04:19 AM, lipska the kat wrote:
>> Well we don't want to turn this into a language comparison thread do we,
>> that might upset too many people but I can't remember ever writing a
>> method that took an Object as argument, you just can't do that much with
>> an Object.
>
> In the pre-Java-1.5 days, functions that took Objects were *very*
> common;

Well the Collections framework does expose methods that take Objects but
generally you override certain methods in class Object when you want to
compare Objects, in fact String comparison is a really interesting area
due to the way Java internalizes Strings at compile time... but that is
way to off topic for here.

regards

Jan Kuiken

unread,
Aug 23, 2012, 2:02:00 PM8/23/12
to
On 8/23/12 06:11 , Steven D'Aprano wrote:

>> 2) Related to the above, you can infinitely nest scopes. There's nothing
>> wrong with having six variables called 'q'; you always use the innermost
>> one. Yes, this can hurt readability
>
> Well, there you go. There *is* something wrong with having six variables
> called 'q'.

Sometimes you don't want only six variables called 'q' but a hundred
of them :-)

def fac(q):
if q < 1 :
return 1
else:
return q * fac(q-1)

print(fac(100))


Jan Kuiken

Ian Kelly

unread,
Aug 23, 2012, 2:17:37 PM8/23/12
to Python
That's only one variable called 'q', instantiated 100 times simultaneously.
Message has been deleted

Evan Driscoll

unread,
Aug 23, 2012, 3:22:08 PM8/23/12
to Steven D'Aprano, pytho...@python.org
On 08/23/2012 12:56 PM, Steven D'Aprano wrote:
> On Thu, 23 Aug 2012 12:17:03 -0500, Evan Driscoll wrote:
>
>> I definitely *wouldn't* say "Python
>> classes aren't really classes" -- even though (I assert) Python classes
>> are *far* further from Simula-style (/Java/C++) classes than Python
>> variables are from Java variables.
>
> Well, Python classes are first-class (pun not intended) objects in their
> own right, and hence are data. Java and C++ classes are not, they are
> instructions to the compiler rather than data.
>
> But other than that, what do you see as the difference between Python
> classes and Simula-style classes?

So first, to some extent that's like saying "these two different things
are different in this important way, but other than that, what's the
difference?" :-)

But there are some other differences. (Not all of these are strictly
with classes per se, but I would say they all have strong interactions
with the object system.)

* Explicit 'self'. OK, this sounds just like a minor syntactic
difference, and in some respect it is. (For some time I considered it
an annoying piece of syntactic salt.) But it has significant
interactions with other things which you can do, such as using a
method as just a normal function ('type(c).f(c)' ~= 'c.f()')
or attaching other functions to an instance or a class (more on that
later).

This is definitely my weakest argument. :-)

* Fields. In Simula-style classes, you can tell easily what fields a
class and its objects contain. In Python, that question from some
point of view doesn't even make sense (in the absence of __slots__).
Fields are a property of the *objects* rather than the class, and
two objects of the same class don't necessarily have the same fields.

Related to this point we have...

* What it means for an object to have a particular class type. With
Simula-style classes, if I have an object 'o' of class 'c', then I
know that 'o' has the functions and fields defined by 'c'. Now, the
virtual functions may have been overriden in base classes and stuff,
and maydbe they'll always fail, but I at least know they're *there*.

In Python, I know... well, nothing basically. As far as I know, it's
possible to make it so that o's only relation to 'c' is what
'type(o)' and 'instanceof' say. (And maybe you can even override
those, I dunno!) You can go through and add/remove/replace functions.
Two different objects of the same class may have completely disjoint
sets of attributes.



> Given:
>
> x = some_object()
> y = x
>
> I could say that x and y are the same object, rather than x and y are
> references to the same object.

Huh, fair enough.


>> To me, saying "here's an alternative way to look at variables" is great,
>> but saying "Python doesn't have variables" is, IMO, at least as silly as
>> what Jussi said. To me, dancing around the issue just leads to more
>> confusing terminology and makes things worse.
>>
>> (And this is reinforced by the fact that neither I nor Google seems to
>> have really seen "Python doesn't have classes" ever used, when that
>> statement is at least as true as "Python doesn't have variables".)
>
> I think you are utterly wrong here.
>
> Python has classes. They are created by the "class" keyword. Whether
> those classes are identical to Java classes is irrelevant -- in Python,
> these whatever-they-are-things are called "classes", and so Python has
> classes.
>
> But Python does not have things called "variables". There is no
> "variable" keyword to create a variable.

OK, let's make a new language. I'll call it 'Python--' because at least
*I* wouldn't want to program in it. :-)

In Python--, any time you use a name, you have to prefix it with the
word 'variable':
variable x = 4
print(variable x)

Does Python-- have variables? Does Python? To me, the answer to those
questions basically has to be the same -- after all, the new 'variable'
keyword didn't really change the language, just have it a slightly
different concrete syntax. Heck, if I wanted to implement Python--, the
only thing I'd have to change in a Python implementation is the lexer!

And if you say "no, Python-- doesn't have variables, it just has
something that it wrongly calls variables", then it's no contradiction
to say "Python doesn't have classes, it just has something that it
wrongly calls classes."

Think of it as duck-typing the term "variable". :-) To me, Python locals
and globals look and quack like a variable.



Incidentally, I also realized another reason I don't like the 'names'
description. Take 'foo.bar'. (That is, the 'bar' attribute in object
'foo'.) Is 'foo.bar' a name? I'm not sure what the 'names' proponents
would say, but to me both answers are problematic. I *really* dislike a
'no' answer because to me, 'foo.bar' absolutely *is* a name for the
corresponding object. (This terminology has precedent.) But a 'yes'
answer, if you also reject 'variable', means you no longer have an
agreed-upon term for the names that are defined in the current scope --
and such a term is a really good thing to have! (<cheeky>I know, let's
call them variables. :-)</cheeky>)

Evan

signature.asc

Jan Kuiken

unread,
Aug 23, 2012, 4:43:41 PM8/23/12
to
On 8/23/12 20:17 , Ian Kelly wrote:

...

>>> Well, there you go. There *is* something wrong with having six variables
>>> called 'q'.

>> Sometimes you don't want only six variables called 'q' but a hundred
>> of them :-)
>>
>> def fac(q):
>> if q < 1 :
>> return 1
>> else:
>> return q * fac(q-1)
>>
>> print(fac(100))

> That's only one variable called 'q', instantiated 100 times simultaneously.

Bare with me, i come from a C world, and think of each variable,
whatever its name or scope, as a piece of memory and therefore
different.
btw. I like the idea of simultaneously instantiation :-)

Jan Kuiken

Chris Angelico

unread,
Aug 23, 2012, 6:00:59 PM8/23/12
to pytho...@python.org
On Fri, Aug 24, 2012 at 3:56 AM, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
> But name bindings are a kind of variable. Named memory locations are a
> *different* kind of variable. The behaviour of C variables and Python
> variables do not follow the Liskov Substitution Principle -- you can't
> rip out the entire "names bound to objects" machinery of Python and
> replace it with C-like named memory locations without changing the high-
> level behaviour of Python. And so by some ways of thinking it is *wrong*
> to treat name bindings and memory locations as "the same sort of entity".
> Hence, if C variables are variables, then Python name bindings can't be.

Yet Python's variables are extremely close to C's pointer variables.
If you allocate all your "real data" on the heap and do everything
with pointers, you'll have semantics very similar to Python's (except
that things aren't refcounted, so you have massive memory leaks). In
fact, that's how the Python-C API handles things - a PyObject*
basically _is_ a Python object, as far as C's concerned.

But again, that probably doesn't help explain the variables. Unless
you've come from (or can at least imagine) an environment in which you
use pointers for *everything*.

ChrisA

Chris Angelico

unread,
Aug 23, 2012, 7:34:19 PM8/23/12
to pytho...@python.org
On Fri, Aug 24, 2012 at 5:22 AM, Evan Driscoll <dris...@cs.wisc.edu> wrote:
> In Python--, any time you use a name, you have to prefix it with the
> word 'variable':
> variable x = 4
> print(variable x)

That gets really unwieldy. You should shorten it to a single symbol.
And your language could be called Python Hypertext Preprocessor.

ChrisA

Ben Finney

unread,
Aug 23, 2012, 7:49:41 PM8/23/12
to
Steven D'Aprano <steve+comp....@pearwood.info> writes:

> No offence to Ben Finney, but I think sometimes he's a bit too eager
> to emphasise the subtle differences between Python and other
> languages, rather than the similarities.

No offense taken.

> Again, context is important:

Indeed. Note that my assertion was in response to someone *already*
confused by pre-conceived notions about what “variable” means, and
misguided attempts to apply those to Python.

If it's over-eager to attempt to head off such confusion in others who
might be reading, then I deny the charge. Others have said it helps, so
I'll keep doing it.

> I don't think the differences are important enough to *prohibit* use of
> the word "variable" to describe name bindings. Only to discourage it.

I wholly agree.

--
\ “Facts do not cease to exist because they are ignored.” —Aldous |
`\ Huxley |
_o__) |
Ben Finney
Message has been deleted
Message has been deleted

Chris Angelico

unread,
Aug 23, 2012, 8:01:17 PM8/23/12
to pytho...@python.org
On Fri, Aug 24, 2012 at 9:54 AM, Dennis Lee Bieber
<wlf...@ix.netcom.com> wrote:
> On Fri, 24 Aug 2012 08:00:59 +1000, Chris Angelico <ros...@gmail.com>
> declaimed the following in gmane.comp.python.general:
>
>>
>> But again, that probably doesn't help explain the variables. Unless
>> you've come from (or can at least imagine) an environment in which you
>> use pointers for *everything*.
>>
> ... but can not manipulate the pointer directly <G>

Right, obviously pointer arithmetic doesn't make sense in Python. But
that's (almost) guaranteed by the fact that there is NOTHING you can
do with bare integers.

foo q = new q; /* note that 'foo' is a typedef that hides the asterisk */
foo w = q +1; /* Pointer arith! Impossible. */

But!

foo e = q + one; /* one is the object representing the integer 1 */

This isn't pointer arithmetic. No C compiler will let you add two
pointers. You can subtract one from another, but you get back a bare
integer, which won't go into a 'foo', so the only thing you could do
that would break stuff is:

foo r = q + (w - e); /* Syntactically valid */

So you just won't do pointer arith if everything's a pointer.

There, I think I just broke a few minds. My task here is done.

ChrisA

Ben Finney

unread,
Aug 23, 2012, 8:02:19 PM8/23/12
to
Evan Driscoll <dris...@cs.wisc.edu> writes:

> Incidentally, I also realized another reason I don't like the 'names'
> description. Take 'foo.bar'. (That is, the 'bar' attribute in object
> 'foo'.) Is 'foo.bar' a name?

It is a reference. That reference happens to be two names, one within
the other's namespace.

> I'm not sure what the 'names' proponents would say

Who are the “names” proponents? I wouldn't propose that “variable” be
replaced with “name” in all, or even most, cases. As you point out, it's
not a good replacement.

I propose “variable” be replaced by “reference” or “binding”, depending
on what is being discussed.

> but to me both answers are problematic. I *really* dislike a 'no'
> answer because to me, 'foo.bar' absolutely *is* a name for the
> corresponding object. (This terminology has precedent.)

There are two names though: ‘foo’ and ‘bar’. The syntax used combines
those names in a particular way, to specify a reference.

> But a 'yes' answer, if you also reject 'variable', means you no longer
> have an agreed-upon term for the names that are defined in the current
> scope -- and such a term is a really good thing to have!

You've lost me here. I would call those names in the current scope
“names”, and I agree that calling what your example presents “a name” is
confusing.

Have I clarified by rejecting your simple use of “name” in this example?
Does my usage of the term “reference” help, as I think it does in this
and most other comparable examples?

--
\ “The fact of your own existence is the most astonishing fact |
`\ you'll ever have to confront. Don't dare ever see your life as |
_o__) boring, monotonous, or joyless.” —Richard Dawkins, 2010-03-10 |
Ben Finney

Roy Smith

unread,
Aug 23, 2012, 8:36:27 PM8/23/12
to
In article <mailman.3693.1345697...@python.org>,
Evan Driscoll <dris...@cs.wisc.edu> wrote:

> > In fact, Python doesn't have variables ­ not as C or Java programmers
> > would understand the term. What it has instead are references to objects
> > (with names as one kind of reference).
>
> OK, I've seen this said a few times, and I have to ask: what do you mean
> by this? I consider myself pretty decent at Python and other languages,
> and I really don't get it.

I'll take a shot at this.

When I execute:

a = 4

I'm doing two things. The first is to create an object of type int with
a value of 4. I think everybody is OK with that part. The confusing
part comes with the LHS.

In C, or Java, there's a container called "a" which holds a value. In
C, that value is the integer 4, in Java it's an Integer object (well, at
least I think it is, I've never fully groked how Java handles integers).

In Python, there is no container named "a". There is, however, a dict
which exists somewhere in python-space. You can get a reference to this
dict by calling globals(). What the assignment does is effectively:

globals()["a"] = 4

In fact, I can even write it that way and everything works:

>>> globals()["a"] = 42
>>> a
42

Even id() thinks they're the same thing:

>>> id(a)
1755402140
>>> id(globals()["a"])
1755402140

But, notice what happens if I now assign something new to a:

>>> a = 123
>>> id(a)
1755403176

The id has changed! Now, we all know that the id of an object is its
memory address (that's not guaranteed, but in the standard C
implementation of Python, that's what it is).

Now, what if I do something similar in C:

#include <stdio.h>

main() {
int a = 40;
printf("a = %d, &a = %p\n", a, &a);
a = 99;
printf("a = %d, &a = %p\n", a, &a);
}

When I compile and run this, it prints:

a = 40, &a = 0x7fff1911f5bc
a = 99, &a = 0x7fff1911f5bc

Notice that the address of the variable "a" didn't change when I
assigned it a new value. That's what people mean when they say C has
variables and Python doesn't; it just binds names to values.

Chris Angelico

unread,
Aug 23, 2012, 9:34:02 PM8/23/12
to pytho...@python.org
On Fri, Aug 24, 2012 at 10:36 AM, Roy Smith <r...@panix.com> wrote:
> In fact, I can even write it that way and everything works:
>
>>>> globals()["a"] = 42
>>>> a
> 42
>
> Even id() thinks they're the same thing:
>
>>>> id(a)
> 1755402140
>>>> id(globals()["a"])
> 1755402140

Ah, no. What you have there is actually id(4) and nothing to do with a at all.

> But, notice what happens if I now assign something new to a:
>
>>>> a = 123
>>>> id(a)
> 1755403176
>
> The id has changed! Now, we all know that the id of an object is its
> memory address (that's not guaranteed, but in the standard C
> implementation of Python, that's what it is).

And you now have id(123) - of course, it's possible for there to be
two integer objects with the value 123, but what I'm emphasizing is
that you're not looking at a here.

> Now, what if I do something similar in C:
>
> #include <stdio.h>
>
> main() {
> int a = 40;
> printf("a = %d, &a = %p\n", a, &a);
> a = 99;
> printf("a = %d, &a = %p\n", a, &a);
> }
>
> When I compile and run this, it prints:
>
> a = 40, &a = 0x7fff1911f5bc
> a = 99, &a = 0x7fff1911f5bc
>
> Notice that the address of the variable "a" didn't change when I
> assigned it a new value. That's what people mean when they say C has
> variables and Python doesn't; it just binds names to values.

Try this instead. It's C++ not C but a much closer match. You could
instead play with malloc if you want it to be C.

#include <stdio.h>

main()
{
int *a=new int(40);
printf("a = %d, id(a) = %p\n",*a,a);
a=new int(99);
printf("a = %d, id(a) = %p\n",*a,a);
}

I've not tested the code and may have a syntax issue with "new
int(40)" (who ever allocates a single int on the heap??) but you get
the idea. At no point do you ever look at, or need to look at, &a.
That's utterly irrelevant.

ChrisA

alex23

unread,
Aug 23, 2012, 11:17:14 PM8/23/12
to
On Aug 24, 11:34 am, Chris Angelico <ros...@gmail.com> wrote:
> On Fri, Aug 24, 2012 at 10:36 AM, Roy Smith <r...@panix.com> wrote:
> > Even id() thinks they're the same thing:
> >>>> id(a)
> > 1755402140
> >>>> id(globals()["a"])
> > 1755402140
>
> Ah, no. What you have there is actually id(4) and nothing to do with a at all.

Well, nothing expect for the fact that he's demonstrating Python
references and how they bind to objects. Sure, id() isn't doing any
lookup, but that's missing the point.

> > But, notice what happens if I now assign something new to a:
>
> >>>> a = 123
> >>>> id(a)
> > 1755403176
>
> > The id has changed!  Now, we all know that the id of an object is its
> > memory address (that's not guaranteed, but in the standard C
> > implementation of Python, that's what it is).
>
> And you now have id(123) - of course, it's possible for there to be
> two integer objects with the value 123, but what I'm emphasizing is
> that you're not looking at a here.

But Roy's point was that referring to 'a' as a 'variable' makes no
sense, as it's not an allocated piece of memory. In fact, he even said
"the id of an object" and not "the id of 'a'" so I'm not entirely sure
what you're objecting to here. You don't need to emphasise anything as
_that was the point_: you're _not_ looking at 'a' _ever_, you're only
ever looking at the object to which it refers.

Antoon Pardon

unread,
Aug 24, 2012, 3:38:48 AM8/24/12
to pytho...@python.org
On 23-08-12 01:58, Ben Finney wrote:
>
> You haven't discovered anything about types; what you have discovered is
> that Python name bindings are not variables.
>
> In fact, Python doesn't have variables – not as C or Java programmers
> would understand the term. What it has instead are references to objects
> (with names as one kind of reference).
>
> The documentation unfortunately calls these references “variables” in
> various places, which IMO compounds the confusion in newcomers
> experienced with other languages. It's best, I think, to reject the idea
> that Python has variables, and think in terms of references instead.
>
Why should we reject the idea that python has variables? Python
variables are a lot like scheme or smalltalk variables and I never
heard anyone having a problem considering these languages
having variables.

Antoon Pardon

unread,
Aug 24, 2012, 4:03:29 AM8/24/12
to pytho...@python.org
Never mind. I missed the reactions already dealing with this.

--
Antoon Pardon

Evan Driscoll

unread,
Aug 24, 2012, 5:14:27 AM8/24/12
to alex23, pytho...@python.org
On 8/23/2012 22:17, alex23 wrote:
> But Roy's point was that referring to 'a' as a 'variable' makes no
> sense, as it's not an allocated piece of memory.

Does the computer just remember what 'a' refers to by keeping notes
about it in Narnia?

Put it this way. If C removed the & operator -- and thus you couldn't
tell what address a variable (or "variable instance", if you prefer) was
at -- would "int x;" cease to be a variable?

Evan


signature.asc

Steven D'Aprano

unread,
Aug 24, 2012, 6:00:26 AM8/24/12
to
On Fri, 24 Aug 2012 04:14:27 -0500, Evan Driscoll wrote:

> On 8/23/2012 22:17, alex23 wrote:
>> But Roy's point was that referring to 'a' as a 'variable' makes no
>> sense, as it's not an allocated piece of memory.
>
> Does the computer just remember what 'a' refers to by keeping notes
> about it in Narnia?

No. The compiler remembers the address of 'a' by keeping notes about it
somewhere in memory during the compilation process. When you run the
compiled program, there is no longer any reference to the name 'a'.

(Many compilers give you the option to keep variable names, but that's
additional debugging data, not an essential part of the execution model.)

The mapping of name:address is part of the *compilation* process -- the
compiler knows that variable 'x' corresponds to location 12345678, but
the compiled code has no concept of anything called 'x'. It only knows
about locations. The source code 'x = 42' is compiled into something like
'store 42 into location 12345678'. (Locations may be absolute or
relative.)

In languages with name bindings, the compiler doesn't need to track
name:address pairs. The compiled application knows about names, but not
about addresses. The source code 'x = 42' is compiled into something like
'store 42 into the namespace using key "x"'.

Python gives you no way to peek at an address. It's not even clear what
the address of the variable would be, because there are *at least three*
things it could be:

1) the address of the key field in the namespace (where the name lives);

2) the address of the value field in the namespace (where the pointer to
the object lives);

3) the address of the object itself.

And any of these are free to move around during the lifetime of the
application. (E.g. in Jython, which runs under the JVM, objects don't
have a fixed location.)


> Put it this way. If C removed the & operator -- and thus you couldn't
> tell what address a variable (or "variable instance", if you prefer) was
> at -- would "int x;" cease to be a variable?

Not at all. Just because the public interface of the language doesn't
give you any way to view the fixed locations of variables, doesn't mean
that variables cease to have fixed locations.



--
Steven

Steven D'Aprano

unread,
Aug 24, 2012, 6:06:33 AM8/24/12
to
On Thu, 23 Aug 2012 20:36:27 -0400, Roy Smith wrote:

> The id has changed! Now, we all know that the id of an object is its
> memory address (that's not guaranteed, but in the standard C
> implementation of Python, that's what it is).

It's not only "not guaranteed", it is *explicitly* noted as an
implementation detail. The id of the object is an arbitrary number
guaranteed to be unique during the lifetime of that object. It just
happens that CPython currently uses the memory address as the id. Jython
does not:

steve@runes:~$ jython
Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19)
[OpenJDK Client VM (Sun Microsystems Inc.)] on java1.6.0_18
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 42
>>> id(x)
1


Nor does IronPython:

steve@runes:~$ ipy
IronPython 2.6 Beta 2 DEBUG (2.6.0.20) on .NET 2.0.50727.1433
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 42
>>> id(x)
43



--
Steven

Alexander Blinne

unread,
Aug 24, 2012, 9:23:29 AM8/24/12
to
On 23.08.2012 20:30, Dennis Lee Bieber wrote:
> On Thu, 23 Aug 2012 15:33:33 +1000, Chris Angelico <ros...@gmail.com>
> declaimed the following in gmane.comp.python.general:
>> x = 1;
>>
>> In C, this means: Assign the integer 1 to the variable x (possibly
>> with implicit type casting, eg to floating point).
>>
> Or, at an even lower level...
>
> Convert the decimal literal "1" to binary (including type casting)
> to the predeclared type given to the variable "x", and store that binary
> value into the predetermined memory associated with "x".

Not really the way i would view it. The conversion to binary of the
string "1" is part of the parsers and compilers work in order to do what
the language reference says about the meaning of x=1;. The resulting
code would simply store the binary value of an integer 1 (which is
contained in the code as is, nothing has to be converted or typecasted)
into the location corresponding to the variable x. So in C x=1; really
means store integer 1 to the variable x.

Grant Edwards

unread,
Aug 24, 2012, 9:27:23 AM8/24/12
to
On 2012-08-24, Steven D'Aprano <steve+comp....@pearwood.info> wrote:
> On Fri, 24 Aug 2012 04:14:27 -0500, Evan Driscoll wrote:
>
>> On 8/23/2012 22:17, alex23 wrote:
>>> But Roy's point was that referring to 'a' as a 'variable' makes no
>>> sense, as it's not an allocated piece of memory.
>>
>> Does the computer just remember what 'a' refers to by keeping notes
>> about it in Narnia?
>
> No. The compiler remembers the address of 'a' by keeping notes about it
> somewhere in memory during the compilation process.

Ah, but as we are always fond of saying in this group "that's an
implementation detail, and not part of the language definition". The
model where a compiler is "keeping notes about it in Narnia" is also
perfectly valid. However, RAM is easier to find than magic wardrobes,
so the "notes" are usually kept in RAM these days.

--
Grant Edwards grant.b.edwards Yow! You mean you don't
at want to watch WRESTLING
gmail.com from ATLANTA?

Chris Angelico

unread,
Aug 24, 2012, 3:18:53 PM8/24/12
to pytho...@python.org
On Fri, Aug 24, 2012 at 11:27 PM, Grant Edwards <inv...@invalid.invalid> wrote:
> Ah, but as we are always fond of saying in this group "that's an
> implementation detail, and not part of the language definition". The
> model where a compiler is "keeping notes about it in Narnia" is also
> perfectly valid. However, RAM is easier to find than magic wardrobes,
> so the "notes" are usually kept in RAM these days.

Maybe, but once you found that wardrobe, you'd have enough storage for
all your needs, AND it takes no time at all to retrieve it! I think we
should start developing NarPy at once.

ChrisA

Steven D'Aprano

unread,
Aug 24, 2012, 10:05:29 PM8/24/12
to
On Thu, 23 Aug 2012 14:22:08 -0500, Evan Driscoll wrote:

> On 08/23/2012 12:56 PM, Steven D'Aprano wrote:
>> On Thu, 23 Aug 2012 12:17:03 -0500, Evan Driscoll wrote:
>>
>>> I definitely *wouldn't* say "Python
>>> classes aren't really classes" -- even though (I assert) Python
>>> classes are *far* further from Simula-style (/Java/C++) classes than
>>> Python variables are from Java variables.
>>
>> Well, Python classes are first-class (pun not intended) objects in
>> their own right, and hence are data. Java and C++ classes are not, they
>> are instructions to the compiler rather than data.
>>
>> But other than that, what do you see as the difference between Python
>> classes and Simula-style classes?
>
> So first, to some extent that's like saying "these two different things
> are different in this important way, but other than that, what's the
> difference?" :-)

Yes, exactly. I acknowledge a difference between the two, and ask you
what differences you see.

Many languages do not have "first-class functions" -- you cannot pass a
function to another function as an argument, or generate them on the fly
at runtime. But the ability of functions to be treated as data is not an
essential part of being-a-function, so I see no problem with describing
both Pascal functions and Python functions as functions.

Likewise, being able to pass classes around as data and generate them on
the fly is not an essential part of being-a-class, to I see no problem
with describing both Java classes and Python classes as classes.


> But there are some other differences. (Not all of these are strictly
> with classes per se, but I would say they all have strong interactions
> with the object system.)

I don't believe that any of those differences in behaviour are either
critical, or (as you acknowledge) strictly in the concept of *class*
itself. I think they're interesting differences, but I don't think they
are essential to the nature of "classness" in the same way that having a
fixed memory address is essential to the nature of "memory location
variable" or a name in a namespace is essential to "name binding
variable".


[...]
>> Python has classes. They are created by the "class" keyword. Whether
>> those classes are identical to Java classes is irrelevant -- in Python,
>> these whatever-they-are-things are called "classes", and so Python has
>> classes.
>>
>> But Python does not have things called "variables". There is no
>> "variable" keyword to create a variable.
>
> OK, let's make a new language. I'll call it 'Python--' because at least
> *I* wouldn't want to program in it. :-)
>
> In Python--, any time you use a name, you have to prefix it with the
> word 'variable':
> variable x = 4
> print(variable x)
>
> Does Python-- have variables?

Of course, because that's what Python-- calls them. Whether Python-- is
*justified* in calling them variables is a more interesting question.

I think it is, in the sense that name bindings are a kind of variable,
and fixed memory locations are a different kind of variable. But I also
think that it isn't, for exactly the reasons why I prefer to describe
Python (without the minuses) as having name bindings rather than
variables "in the C or Pascal sense".

Ultimately what is important are the semantics of the words, not the
words themselves. Objections to use of "variable" are, I believe,
*pragmatic* objections that the word comes with too much baggage to be
safe to use, not that name bindings aren't a type of variable.


> Think of it as duck-typing the term "variable". :-) To me, Python locals
> and globals look and quack like a variable.

And so they should, since name bindings are a way of implementing the
abstract Variable kind, so to speak.


> Incidentally, I also realized another reason I don't like the 'names'
> description. Take 'foo.bar'. (That is, the 'bar' attribute in object
> 'foo'.) Is 'foo.bar' a name?

Is "Evan Driscoll" a name? Or is it two names?

There is no contradiction to say that "Evan Driscoll" is both a name (a
"compound name", if you like, or fully-qualified name) and two names (a
personal name plus a family name).

foo.bar is both a fully-qualified name and two names: the name of the
namespace and the name of the attribute in the namespace.


> I'm not sure what the 'names' proponents
> would say, but to me both answers are problematic. I *really* dislike a
> 'no' answer because to me, 'foo.bar' absolutely *is* a name for the
> corresponding object. (This terminology has precedent.) But a 'yes'
> answer, if you also reject 'variable', means you no longer have an
> agreed-upon term for the names that are defined in the current scope

"Local names".

We also have "global names" for those in the global scope, "builtin
names" for those in the built-ins, and "nonlocal names".



--
Steven

Steven D'Aprano

unread,
Aug 24, 2012, 11:04:38 PM8/24/12
to
On Fri, 24 Aug 2012 08:00:59 +1000, Chris Angelico wrote:

> On Fri, Aug 24, 2012 at 3:56 AM, Steven D'Aprano
> <steve+comp....@pearwood.info> wrote:
>> But name bindings are a kind of variable. Named memory locations are a
>> *different* kind of variable. The behaviour of C variables and Python
>> variables do not follow the Liskov Substitution Principle -- you can't
>> rip out the entire "names bound to objects" machinery of Python and
>> replace it with C-like named memory locations without changing the
>> high- level behaviour of Python. And so by some ways of thinking it is
>> *wrong* to treat name bindings and memory locations as "the same sort
>> of entity". Hence, if C variables are variables, then Python name
>> bindings can't be.
>
> Yet Python's variables are extremely close to C's pointer variables.

Not really. Pointer variables are no different from any other variable:
you have a named memory location that contains some data. In this case,
the data happens to be a link to another chunk of memory. The pointer
variable itself is just a named location containing data, same as a char
variable, a float variable, etc. The data is a pointer rather than a char
or float, and the operations which you can do to pointers are different
to those you can do to chars or floats, but that's true of any data type.

In languages without pointers, like Fortran 77, you can more or less
simulate them with a fixed array of memory as the heap, with integer
indexes into that array as pointers. These "pointer variables" are no
different from other "integer variables" except in the meaning you, the
programmer, gives them. This is no different from how C or Pascal treat
pointers, except that those languages have syntactical support for
pointer operations and Fortran 77 doesn't.


> If
> you allocate all your "real data" on the heap and do everything with
> pointers, you'll have semantics very similar to Python's

You're confusing two different levels of explanation here. On the one
hand, you're talking about C semantics, where you are explicitly
responsible for managing unnamed data via indirection (pointers).
Typically, the *pointers* get given names, the data does not.

On the other hand, you talk about Python, where you have no access at all
to the pointers and memory addresses. You manage the data you actually
care about by giving them names, and then leave it up to the Python
virtual machine to transparently manage whatever indirection is needed to
make it work.

The fact that the end result is the same is hardly surprising -- Python's
VM is built on top of C pointer indirection, so of course you can start
with pointers and end up with Python semantics. But the practice of
coding are very different:

* in C, I care about identifiers ("names") in order to explicitly manage
addresses and pointers as a means to reach the data I actually care about;

* in Python, I care about identifiers in order to reach the data I
actually care about.



--
Steven

Ben Finney

unread,
Aug 25, 2012, 1:24:29 AM8/25/12
to
Steven D'Aprano <steve+comp....@pearwood.info> writes:

> On Thu, 23 Aug 2012 14:22:08 -0500, Evan Driscoll wrote:
>
> > In [the hypothetical language] Python--, any time you use a name,
> > you have to prefix it with the word 'variable':
> > variable x = 4
> > print(variable x)
> >
> > Does Python-- have variables?
>
> Of course, because that's what Python-- calls them. Whether Python--
> is *justified* in calling them variables is a more interesting
> question.

How many legs does a horse have, if you call the tail a leg?

Four. Calling the tail a leg doesn't make it so.


Similarly, I don't care that Python-- uses the term “variable”, it only
has variables if it has things which meet a sensible definition of
“variable”. So no, “because that's what Python-- calls them” is not
sufficient.

> I think it is, in the sense that name bindings are a kind of variable,
> and fixed memory locations are a different kind of variable. But I
> also think that it isn't, for exactly the reasons why I prefer to
> describe Python (without the minuses) as having name bindings rather
> than variables "in the C or Pascal sense".

To emphasise what may not be apparent to some newcomers, Steven and I
are virtually in exact agreement here. We talk more about where we
differ because that's what interests us :-)

--
\ “In the long run, the utility of all non-Free software |
`\ approaches zero. All non-Free software is a dead end.” —Mark |
_o__) Pilgrim, 2006 |
Ben Finney

Chris Angelico

unread,
Aug 25, 2012, 2:34:50 AM8/25/12
to pytho...@python.org
On Sat, Aug 25, 2012 at 1:04 PM, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
> You're confusing two different levels of explanation here. On the one
> hand, you're talking about C semantics, where you are explicitly
> responsible for managing unnamed data via indirection (pointers).
> Typically, the *pointers* get given names, the data does not.
>
> On the other hand, you talk about Python, where you have no access at all
> to the pointers and memory addresses. You manage the data you actually
> care about by giving them names, and then leave it up to the Python
> virtual machine to transparently manage whatever indirection is needed to
> make it work.
> ...
> * in C, I care about identifiers ("names") in order to explicitly manage
> addresses and pointers as a means to reach the data I actually care about;
>
> * in Python, I care about identifiers in order to reach the data I
> actually care about.

Yet the two are almost the same. Python objects don't have names, they
just have their own data. (Leaving aside functions, which have their
names as data for the benefit of tracebacks and such.) A C pointer has
a name; a Python identifier has (or is, if you like) a name. They're
very different in how you use them only because C doesn't naturally
work with everything on the heap and pointers everywhere. In fact,
when I was interfacing Python and C, there were a few places where I
actually handed objects to Python and kept manipulating them, simply
because the Python data model suited what I was trying to do; but what
I was doing was using PyObject *some_object as though it were a Python
variable. I even did up a trivial C++ class that encapsulated the
INCREF/DECREF work, so my LocalPyObject really could be treated as a
local variable, Python-style.

Where's the difference?

ChrisA

Mark Lawrence

unread,
Aug 25, 2012, 4:55:27 AM8/25/12
to pytho...@python.org
On 25/08/2012 07:34, Chris Angelico wrote:
> On Sat, Aug 25, 2012 at 1:04 PM, Steven D'Aprano

I'm just wondering out aloud if the number of times this type of thread
has been debated here will fit into a Python long or float?

--
Cheers.

Mark Lawrence.

Chris Angelico

unread,
Aug 25, 2012, 6:23:46 AM8/25/12
to pytho...@python.org
On Sat, Aug 25, 2012 at 6:55 PM, Mark Lawrence <bream...@yahoo.co.uk> wrote:
> I'm just wondering out aloud if the number of times this type of thread has
> been debated here will fit into a Python long or float?

Well, when I have to store currency information, I like to store it as
an integer, using the native currency's "small unit" (eg the cent in
dollar+cent currencies). In this instance, instead of trying to count
the threads (which would be fractional), just count the number of
posts. It then is an integer, and I've yet to find any integer that
can't be represented as a Python long (or, in 3.x, int).

ChrisA

Mark Lawrence

unread,
Aug 25, 2012, 7:01:07 AM8/25/12
to pytho...@python.org
That could have been fun in the good old days of pounds, shillings and
pence. Why they had to complicate things by going decimal I shall never
know. Bring back simplistic imperial measures for everything, that's
what I say.

Using long just shows I've still got a Python 2 hat on. Still when
those fine people who develop Matplotlib deliver 1.2 with its Py3k
compliance, aided or hindered by me testing on Windows, Python 3.3 here
I come.

I suppose an alternative to long (or int) or float would have been the
Decimal class from the decimal module? Opinions on this anybody?

--
Cheers.

Mark Lawrence.

Message has been deleted

Chris Angelico

unread,
Aug 25, 2012, 7:27:14 PM8/25/12
to pytho...@python.org
On Sun, Aug 26, 2012 at 5:56 AM, Dennis Lee Bieber
<wlf...@ix.netcom.com> wrote:
> On Sat, 25 Aug 2012 09:55:27 +0100, Mark Lawrence
> <bream...@yahoo.co.uk> declaimed the following in
> gmane.comp.python.general:
>
>>
>> I'm just wondering out aloud if the number of times this type of thread
>> has been debated here will fit into a Python long or float?
>
> Well, since I don't think one can have a fractional debate (maybe if
> someone starts a thread and NOBODY ever follows up on it), then float's
> don't gain us anything there.
>
> Presuming a double-precision float, we would have 14-15 significant
> digits for the mantissa -- so anything greater than
> (9)99,999,999,999,999 will have lost accuracy. In contrast Python longs
> have effectively unlimited significant digits.

I wonder if some people are applying an alternative form of duck
typing - if it quacks like a "should Python have variables" debate, it
gets silenced with that universal grey tape...

ChrisA
Message has been deleted

Evan Driscoll

unread,
Aug 26, 2012, 1:25:06 AM8/26/12
to Steven D'Aprano, pytho...@python.org
On 08/24/2012 10:04 PM, Steven D'Aprano wrote:
> The fact that the end result is the same is hardly surprising -- Python's
> VM is built on top of C pointer indirection, so of course you can start
> with pointers and end up with Python semantics. But the practice of
> coding are very different:
>
> * in C, I care about identifiers ("names") in order to explicitly manage
> addresses and pointers as a means to reach the data I actually care about;
>
> * in Python, I care about identifiers in order to reach the data I
> actually care about.
>
So I find this comment very interesting. It makes me wonder if the root
cause of our (pretty minor) disagreement is in some sense related to our
mental models of *C* variables. I'm actually not much of a C programmer
specifically, but I do a lot of C++ stuff. Of those two descriptions,
I'd actually say that the Python description sounds more like how I
think about variables in C++ most of the time.

Obviously there are differences between value and reference semantics
between the two languages, but thinking about some variable being
located at some address in memory is something that I actually do pretty
rarely; I basically think of variables as naming data, and addresses
mostly come into play when thinking about points-to and aliasing
information at a more abstract level, much the same as I do in Python.

Evan

Evan Driscoll

unread,
Aug 26, 2012, 1:45:55 AM8/26/12
to Steven D'Aprano, pytho...@python.org
On 08/24/2012 05:00 AM, Steven D'Aprano wrote:
> No. The compiler remembers the address of 'a' by keeping notes about it
> somewhere in memory during the compilation process. When you run the
> compiled program, there is no longer any reference to the name 'a'.
>
> ...
>
> The mapping of name:address is part of the *compilation* process -- the
> compiler knows that variable 'x' corresponds to location 12345678, but
> the compiled code has no concept of anything called 'x'. It only knows
> about locations. The source code 'x = 42' is compiled into something like
> 'store 42 into location 12345678'. (Locations may be absolute or
> relative.)
>
> In languages with name bindings, the compiler doesn't need to track
> name:address pairs. The compiled application knows about names, but not
> about addresses. The source code 'x = 42' is compiled into something like
> 'store 42 into the namespace using key "x"'.
What you describe is sorta correct, but it's also not... you're
describing implementations rather than the language. And while the
language semantics certainly impose restrictions on the implementation,
I think in this case the situation is closer than you acknowledge:


From the Python side, I suspect that for most functions, you'd be able
to create a Python implementation that behaves more like C, and
allocates locals in a more traditional fashion. I don't know much about
it, but I'd guess that PyPy already does something along this line;
someone also mentioned that Cython (admittedly not a full-blown Python
implementation, but close for the purpose of this question) tries to do
the same thing.


On the C side, imagine a function with locals x, y, and z which never
takes the address of any of them. (You said later that "Just because the
public interface of the language doesn't give you any way to view the
fixed locations of variables, doesn't mean that variables cease to have
fixed locations.")

First, C variables may not even have a memory address. They can
disappear completely during compilation, or live in a register for their
entire life.

Second, it's possible that those variables *don't* occupy a fixed
location. If you never explicitly take an address of a variable (&x),
then I can't think of any way that the address can be observed without
invoking undefined behavior -- and this means the C compiler is free to
transform it to anything that is equivalent under the C semantics. In
particular, it can split uses of a variable into multiple ones if there
are disjoint live ranges. For instance, in:
x = 5
print x
x = 10
print x
there are two live ranges of x, one consisting of lines 1 and 2, and one
consisting of lines 3 and 4. These live ranges could have been different
variables; I could just of easily have written
x = 5
print x
y = 10
print y
and these pieces of code are observationally equivalent, so the compiler
is allowed to generate the same code for both. In particular, it could
either compile the second example to share the same memory address for x
and y (meaning that a memory address isn't uniquely named by a single
variable) or it could compile the first to put the two live ranges of x
into different memory addresses (meaning that a variable doesn't
uniquely name a memory address). In fact, I'd *expect* an optimizing
compiler to share memory for x and y, and I'd also expect to be able to
concoct an example where different live ranges of one variable wind up
at different addresses. (The latter I'm less sure of though, and I also
expect it'd be a little hard, as you'd have to come up with an example
where even at the high optimization levels you'd need to see that, both
live ranges would wind up in memory.)

Third, and more wackily, you could technically create a C implementation
that works like Python, where it stores variables (whose addresses
aren't taken) in a dict keyed by name, and generates code that on a
variable access looks up the value by accessing that dict using the name
of the variable.

Evan

88888 Dihedral

unread,
Aug 26, 2012, 2:14:52 AM8/26/12
to
Jan Kuiken於 2012年8月24日星期五UTC+8上午2時02分00秒寫道:
> On 8/23/12 06:11 , Steven D'Aprano wrote:
>
>
>
> >> 2) Related to the above, you can infinitely nest scopes. There's nothing
>
> >> wrong with having six variables called 'q'; you always use the innermost
>
> >> one. Yes, this can hurt readability
>
> >
>
> > Well, there you go. There *is* something wrong with having six variables
>
> > called 'q'.
>
>
>
> Sometimes you don't want only six variables called 'q' but a hundred
>
> of them :-)
>
>
>
> def fac(q):
>
> if q < 1 :
>
> return 1
>
> else:
>
> return q * fac(q-1)
>
>
>
> print(fac(100))
>


>
>
>
>
> Jan Kuiken

The long integer arithmetic operations are built in.
This makes mathematicians and designers focused on the theory side.


Chris Angelico

unread,
Aug 26, 2012, 2:22:05 AM8/26/12
to pytho...@python.org
On Sun, Aug 26, 2012 at 3:45 PM, Evan Driscoll <dris...@cs.wisc.edu> wrote:
> Third, and more wackily, you could technically create a C implementation
> that works like Python, where it stores variables (whose addresses aren't
> taken) in a dict keyed by name, and generates code that on a variable access
> looks up the value by accessing that dict using the name of the variable.

That would be a reasonable way to build a C interactive interpreter.

ChrisA

Steven D'Aprano

unread,
Aug 26, 2012, 8:02:35 AM8/26/12
to
No it wouldn't. Without fixed addresses, the language wouldn't be able to
implement pointers. C without pointers isn't C, it is something else.
Possibly called Python :)

I suppose you could get pointers in Namespace-C if you somehow mapped
names to addresses, and vice versa, but why would you do that? You end up
with a hybrid system that doesn't give you any advantage over C but has a
much more complicated implementation (and therefore many more new and
exciting bugs).

But if you want me to agree that you could implement C using name
binding, plus some weird scheme to track memory addresses, then yes, I
suppose you could. Then the parts of C that don't rely on fixed memory
addresses could use the name bindings (with the corresponding loss of
performance), and the parts of C which do require them could continue to
do so, and we'll have one more language with a confusing, unclear and
unclean execution model. Everybody wins! For some definition of win.



--
Steven

Chris Angelico

unread,
Aug 26, 2012, 9:34:57 AM8/26/12
to pytho...@python.org
On Sun, Aug 26, 2012 at 10:02 PM, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
> On Sun, 26 Aug 2012 16:22:05 +1000, Chris Angelico wrote:
>
>> On Sun, Aug 26, 2012 at 3:45 PM, Evan Driscoll <dris...@cs.wisc.edu>
>> wrote:
>>> Third, and more wackily, you could technically create a C
>>> implementation that works like Python, where it stores variables (whose
>>> addresses aren't taken) in a dict keyed by name, and generates code
>>> that on a variable access looks up the value by accessing that dict
>>> using the name of the variable.
>>
>> That would be a reasonable way to build a C interactive interpreter.
>
> No it wouldn't. Without fixed addresses, the language wouldn't be able to
> implement pointers. C without pointers isn't C, it is something else.
> Possibly called Python :)

The insertion of a single rule will do it. Let it stand that &x is the
string "x" and there you are, out of your difficulty at once!

Okay, that may be a bit of a fairy tale ending and completely illogical.

ChrisA

Roy Smith

unread,
Aug 26, 2012, 9:41:07 AM8/26/12
to
In article <mailman.3830.1345962...@python.org>,
Except that lots of C and C++ programs assume they know how data
structures are laid out and can index forward and backward over them in
ways which the language does not promise work (but are, none the less,
useful). Say, the sort of thinks you might use python's struct module
for.

On the other hand, there is certainly a big subset of C that you could
implement that way. But it would only be useful as a simple
instructional tool.

Steven D'Aprano

unread,
Aug 26, 2012, 9:43:33 AM8/26/12
to
On Sun, 26 Aug 2012 00:45:55 -0500, Evan Driscoll wrote:

> On 08/24/2012 05:00 AM, Steven D'Aprano wrote:
>> No. The compiler remembers the address of 'a' by keeping notes about it
>> somewhere in memory during the compilation process. When you run the
>> compiled program, there is no longer any reference to the name 'a'.
>>
>> ...
>>
>> The mapping of name:address is part of the *compilation* process -- the
>> compiler knows that variable 'x' corresponds to location 12345678, but
>> the compiled code has no concept of anything called 'x'. It only knows
>> about locations. The source code 'x = 42' is compiled into something
>> like 'store 42 into location 12345678'. (Locations may be absolute or
>> relative.)
>>
>> In languages with name bindings, the compiler doesn't need to track
>> name:address pairs. The compiled application knows about names, but not
>> about addresses. The source code 'x = 42' is compiled into something
>> like 'store 42 into the namespace using key "x"'.
>
> What you describe is sorta correct, but it's also not... you're
> describing implementations rather than the language. And while the
> language semantics certainly impose restrictions on the implementation,

I accept that languages may choose to leave the variable-model
unspecified. I don't think they can define behaviour without implying one
model or the other. Or at least not easily - far too much language
behaviour is tied to the implementation to let us say "it's only
implementation".

For example, the reason that locals() is not writable inside Python
functions is because CPython moves away from the name binding model
inside functions as an optimization. This function prints 1 under both
CPython and Jython (but not IronPython):

def spam():
x = 1
locals()['x'] = 2
print(x)

Binding to the local namespace does not work, because functions don't
*actually* use a namespace, they use something closer to the C model. So
the two models are not interchangable and hence they aren't *just*
implementation details, they actually do affect the semantics of the
language.

I suppose you could arrange for locals() to return a proxy dictionary
which knew about the locations of variables. But what happens if you
returned that proxy to the caller, which then assigned to it later after
the function variables no longer existed?

Similarly, there are operations which are no longer allowed simply
because of the difference between name binding and locational variables:


py> def ham():
... from math import *
...
File "<stdin>", line 1
SyntaxError: import * only allowed at module level


(In some older versions of Python, wildcard imports are allowed, and the
function then falls back on a namespace instead of fixed locations. That
is no longer the case in Python 3.2 at least.)


> I think in this case the situation is closer than you acknowledge:
>
> From the Python side, I suspect that for most functions, you'd be able
> to create a Python implementation that behaves more like C, and
> allocates locals in a more traditional fashion.

As I discuss above, CPython and Jython actually do something like that
inside functions. And there are observable differences in behaviour (not
just performance) between function scope and global scope.

So an implementation of Python which used fixed memory addresses
everywhere, not just in functions, would be detectably different in
behaviour than CPython. Whether those differences would be enough to
disqualify it from being called "Python" is a matter of opinion.

(Probably Guido's opinion is the only one that matters.)


[...]
> On the C side, imagine a function with locals x, y, and z which never
> takes the address of any of them. (You said later that "Just because the
> public interface of the language doesn't give you any way to view the
> fixed locations of variables, doesn't mean that variables cease to have
> fixed locations.")
>
> First, C variables may not even have a memory address. They can
> disappear completely during compilation, or live in a register for their
> entire life.

Variables that don't exist at runtime don't have an address at all -- in
a way, they aren't even a variable any more. They have a name in the
source code, but that's all.

As for registers, they are memory addresses, of a sort. (I didn't mean to
imply that they must live in main motherboard memory.) I call any of
these an address:

- in the heap at address 12345678
- in the GPU's video memory at address 45678
- 12th entry from the top of the stack
- register 4


> Second, it's possible that those variables *don't* occupy a fixed
> location. If you never explicitly take an address of a variable (&x),
> then I can't think of any way that the address can be observed without
> invoking undefined behavior -- and this means the C compiler is free to
> transform it to anything that is equivalent under the C semantics.

I may have been too emphatic about the "fixed" part. A sufficiently
clever compiler may implement its own memory manager (on top of the
operating system's memory manager?) and relocate variables during their
lifetime. But for my purposes, the important factor is that the compiler
knows the address at every moment, even if that address changes from time
to time.

In contrast, a name binding system *doesn't* know the address of a
variable. The analogy I like is making a delivery to a hotel room. C-like
languages say:

"Deliver this package to room 1234."

Pointer semantics are like:

"Go to room 1234 and collect an envelope; deliver this package to the
room number inside the envelope."

On the other hand, name binding languages say:

"Go to the concierge at the front desk and ask for Mr Smith's room, wait
until he looks it up in the register, then deliver this package to the
room number he tells you."

Typically, you don't even have any way to store the room number for later
use. In Python, name lookups involve calculating a hash and searching a
dict. Once you've looked up a name once, there is no way to access the
hash table index to bypass that process for future lookups.

It gets worse: Python has multiple namespaces that are searched.

"Go to the Excelsior Hotel and ask the concierge for Mr Smith. If Mr
Smith isn't staying there, go across the road to the Windsor Hotel and
ask there. If he's not there, try the Waldorf Astoria, and if he's not
there, try the Hyperion."

Considering just how much work Python has to do to simply access a named
variable, it's amazing how slow it isn't.


--
Steven

Chris Angelico

unread,
Aug 26, 2012, 9:58:31 AM8/26/12
to pytho...@python.org
On Sun, Aug 26, 2012 at 11:43 PM, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
> It gets worse: Python has multiple namespaces that are searched.
>
> "Go to the Excelsior Hotel and ask the concierge for Mr Smith. If Mr
> Smith isn't staying there, go across the road to the Windsor Hotel and
> ask there. If he's not there, try the Waldorf Astoria, and if he's not
> there, try the Hyperion."

Does it? I thought the difference between function-scope and
module-scope was compiled in, and everything else boils down to one of
those. Explicit dot notation is different ("ask for Mr Smith, then ask
him where his packages box is, and put this in the box").

Hmm, okay, there's something slightly different with closures. But
it's still unambiguous at compile time.

>>> x=1
>>> def foo(y):
return lambda z: x+y+z

>>> foo(2)(3)
6
>>> import dis
>>> dis.dis(foo(2))
2 0 LOAD_GLOBAL 0 (x)
3 LOAD_DEREF 0 (y)
6 BINARY_ADD
7 LOAD_FAST 0 (z)
10 BINARY_ADD
11 RETURN_VALUE

What multiple namespaces are you talking about, where things have to
get looked up at run time?

ChrisA

Mark Lawrence

unread,
Aug 26, 2012, 10:02:43 AM8/26/12
to pytho...@python.org
On 26/08/2012 14:34, Chris Angelico wrote:
>
> Okay, that may be a bit of a fairy tale ending and completely illogical.
>
> ChrisA
>

Then stick to the thread about flexible string representation, unicode
and typography :)

--
Cheers.

Mark Lawrence.

Roy Smith

unread,
Aug 26, 2012, 10:02:36 AM8/26/12
to
In article <503a2804$0$6574$c3e8da3$5496...@news.astraweb.com>,
Steven D'Aprano <steve+comp....@pearwood.info> wrote:

>>> The mapping of name:address is part of the *compilation* process --
>>> the compiler knows that variable 'x' corresponds to location
>>> 12345678

Just to pick a nit, the compiler probably doesn't know that, but the
linker does (or maybe even the run-time loader). However, we can think
of all of those as just part of the compilation tool chain, and then
we're good.

Chris Angelico

unread,
Aug 26, 2012, 10:05:47 AM8/26/12
to pytho...@python.org
On Mon, Aug 27, 2012 at 12:02 AM, Mark Lawrence <bream...@yahoo.co.uk> wrote:
> On 26/08/2012 14:34, Chris Angelico wrote:
>>
>> Okay, that may be a bit of a fairy tale ending and completely illogical.
>>
>> ChrisA
>
> Then stick to the thread about flexible string representation, unicode and
> typography :)

Hehe. Probably nobody on this list will recognize what I said, but
it's a near-quote from "Iolanthe", an opera about fairies. It's the
great denoumont, the solution to everyone's problems. And in the same
way, redefining the "take-address-of" operator could be a perfect
solution... and, just like in Iolanthe, is a rather fundamental
change, and one that would break a lot of things.

ChrisA
It is loading more messages.
0 new messages