Can a simple a==b 'hang' in and endless loop?

C

Claudio Grondi

In the process of learning about some deeper details of Python I am
curious if it is possible to write a 'prefix' code assigning to a and b
something special, so, that Python gets trapped in an endless loop in a
line with:

if a==b: print 'OK'

I mean, it would be of much help to me on my way to understanding Python
to know how such prefix code leading to an endless loop can look like
and if it is eventually not possible to write such code, to know why it
is not possible?

My own first rough idea was to create generators which never end and use
them in the '==' comparison, but I have not well understood how to write
and use generators yet, so I expect from studying this special case to
come to some enlightenment.

Claudio
 
F

Fredrik Lundh

Claudio said:
In the process of learning about some deeper details of Python I am
curious if it is possible to write a 'prefix' code assigning to a and b
something special, so, that Python gets trapped in an endless loop in a
line with:

if a==b: print 'OK'

I mean, it would be of much help to me on my way to understanding Python
to know how such prefix code leading to an endless loop can look like

since == can be overridden by the objects involved, == can do anything:

http://docs.python.org/ref/customization.html

__lt__ __div__ F __gt__
 
S

Steve Holden

Claudio said:
In the process of learning about some deeper details of Python I am
curious if it is possible to write a 'prefix' code assigning to a and b
something special, so, that Python gets trapped in an endless loop in a
line with:

if a==b: print 'OK'

I mean, it would be of much help to me on my way to understanding Python
to know how such prefix code leading to an endless loop can look like
and if it is eventually not possible to write such code, to know why it
is not possible?

My own first rough idea was to create generators which never end and use
them in the '==' comparison, but I have not well understood how to write
and use generators yet, so I expect from studying this special case to
come to some enlightenment.
Well, you could try this:
... def __eq__(self, other):
... return other == self
...Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in __eq__
File "<stdin>", line 3, in __eq__
File "<stdin>", line 3, in __eq__
...
File "<stdin>", line 3, in __eq__

Was that what you meant? Or something more like:
... def __eq__(self, other):
... import time; time.sleep(1000000)
...
regards
Steve
 
C

Claudio Grondi

Steve said:
Well, you could try this:

... def __eq__(self, other):
... return other == self
...
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in __eq__
File "<stdin>", line 3, in __eq__
File "<stdin>", line 3, in __eq__
...
File "<stdin>", line 3, in __eq__


Was that what you meant? Or something more like:

... def __eq__(self, other):
... import time; time.sleep(1000000)
...

regards
Steve
Thanks for the quick reply.

I see, that I have overseen, that as Fredrik also stated, one can
directly manipulate __eq__() as the easiest way to achieve what I
requested.

To explain why I am not happy with it, I will try here to give some more
background information. Sorry for not doing it directly, but as already
stated I have forgot about the possibility to use __eq__().

In Python the built in '==' operator (when not manipulated in own code)
behaves not as the '==' operator e.g. in C or Javascript, because it
iterates over arrays (i.e. lists) doing many comparisons instead of
comparing only two 'values'. Coming from C or Javascript one would
expect '==' to compare the 'pointers' to the arrays and not to iterate
over all elements of the lists.
With the solution to the question above I intended to have an example of
Python code which outcome is an endless loop and the problem causing it
very hard to find if one thinks in terms of C or Javascript when
considering lists (as arrays) and the function of '==' operator.

Claudio
 
F

Fuzzyman

Claudio Grondi wrote:
[snip..]
Thanks for the quick reply.

I see, that I have overseen, that as Fredrik also stated, one can
directly manipulate __eq__() as the easiest way to achieve what I
requested.

To explain why I am not happy with it, I will try here to give some more
background information. Sorry for not doing it directly, but as already
stated I have forgot about the possibility to use __eq__().

In Python the built in '==' operator (when not manipulated in own code)
behaves not as the '==' operator e.g. in C or Javascript, because it
iterates over arrays (i.e. lists) doing many comparisons instead of
comparing only two 'values'. Coming from C or Javascript one would
expect '==' to compare the 'pointers' to the arrays and not to iterate
over all elements of the lists.

In Python the equality operator ('==') compares values. For sequence
and mapping type objects this can be a (relatively) expensive
operation.

You are probably looking for the identity operator which just
(effectively) compares pointers ('is').

a is b

does more what you would expect.

This is a better system than the ones you describe. :)

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
 
S

Steve Holden

Claudio said:
Thanks for the quick reply.

I see, that I have overseen, that as Fredrik also stated, one can
directly manipulate __eq__() as the easiest way to achieve what I
requested.

To explain why I am not happy with it, I will try here to give some more
background information. Sorry for not doing it directly, but as already
stated I have forgot about the possibility to use __eq__().

In Python the built in '==' operator (when not manipulated in own code)
behaves not as the '==' operator e.g. in C or Javascript, because it
iterates over arrays (i.e. lists) doing many comparisons instead of
comparing only two 'values'. Coming from C or Javascript one would
expect '==' to compare the 'pointers' to the arrays and not to iterate
over all elements of the lists.
With the solution to the question above I intended to have an example of
Python code which outcome is an endless loop and the problem causing it
very hard to find if one thinks in terms of C or Javascript when
considering lists (as arrays) and the function of '==' operator.
If your assertiona about C and Java are correct you would, of course,
describing a deficiency of those languages, where a variable refers to a
reserved area of storage intended to hold a value of a specific type (or
a specific uinion of types).

To the Python user C and Java appear to be confusing "equality" with
"identity". The == operator in C, certainly, compares identity (whether
of values or of pointers to structured values). Frankly I don't choose
to remember enough Java to determine the correctness of your assertion
in that language.

In Python a name is intended to be bound as a reference to an object of
any type whatsoever (the type pf the object is stored as a part of the
value). Equality is generally defined as "has the same value", hence the
ability to define it specifically for user-defined types.

In Python you test for "is the same object" with the "is" operator. As in

regards
Steve
 
C

Claudio Grondi

Fuzzyman said:
Claudio Grondi wrote:
[snip..]
Thanks for the quick reply.

I see, that I have overseen, that as Fredrik also stated, one can
directly manipulate __eq__() as the easiest way to achieve what I
requested.

To explain why I am not happy with it, I will try here to give some more
background information. Sorry for not doing it directly, but as already
stated I have forgot about the possibility to use __eq__().

In Python the built in '==' operator (when not manipulated in own code)
behaves not as the '==' operator e.g. in C or Javascript, because it
iterates over arrays (i.e. lists) doing many comparisons instead of
comparing only two 'values'. Coming from C or Javascript one would
expect '==' to compare the 'pointers' to the arrays and not to iterate
over all elements of the lists.


In Python the equality operator ('==') compares values. For sequence
and mapping type objects this can be a (relatively) expensive
operation.

You are probably looking for the identity operator which just
(effectively) compares pointers ('is').

a is b

does more what you would expect.

This is a better system than the ones you describe. :)

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

With the solution to the question above I intended to have an example of
Python code which outcome is an endless loop and the problem causing it
very hard to find if one thinks in terms of C or Javascript when
considering lists (as arrays) and the function of '==' operator.

Claudio
Yes, I know about 'is',

but I mean, that it is not possible to use 'is' as replacement for '=='
operator to achieve in Python same behaviour as it is the case in C and
Javascript when comparing values with '=='.
'is' does the C, Javascript job when comparing lists, but I mean it
fails to give fully predictable results when applied to elements of
lists in case there exist duplicate objects with same 'value' i.e. e.g.
there are two different objects storing the integer value 1, what I mean
can happen when there is enough other code between the Python code lines
assigning the integer value 1 to a list element or any other identifier.
Or is there in Python a 100% reliable mechanism assuring, that there is
one and _only one_ object carrying a given 'value' (at least for the
built in types as integer, long integer, string, float) and if this
value is to be assigned to a list element or any other literal the
already existing object (if any) will be found and used/referenced?

Claudio
 
C

Claudio Grondi

Steve said:
If your assertiona about C and Java are correct you would, of course,
describing a deficiency of those languages, where a variable refers to a
reserved area of storage intended to hold a value of a specific type (or
a specific uinion of types).

To the Python user C and Java appear to be confusing "equality" with
"identity". The == operator in C, certainly, compares identity (whether
of values or of pointers to structured values). Frankly I don't choose
to remember enough Java to determine the correctness of your assertion
in that language.

In Python a name is intended to be bound as a reference to an object of
any type whatsoever (the type pf the object is stored as a part of the
value). Equality is generally defined as "has the same value", hence the
ability to define it specifically for user-defined types.

In Python you test for "is the same object" with the "is" operator. As in


regards
Steve

The problem here is, that I mean, that in Python it makes no sense to
talk about a value of an object, because it leads to weird things when
trying to give a definition what a value of an object is.

It seems, that in Python there is a lack of operator able to compare
values as it is the case in C and Javascript, simply because in Python
there are no really such things as values, so there is no need to
compare them.

The higher level of abstraction/indirection in Python results in making
the concepts of 'value', 'having a value' or 'comparing values' useless,
where it helps in C to express the difference between address and
content at that address and to distinguish between the information
telling _what_ is stored in memory and the information about _where_ it
is stored.

It appears to me, that the whole subject of what an identifier in Python
represents and if there is such thingy as 'value' in Python, is not
perfectly well understood even by Python experts programming also in
many other languages and therefore the vital differences in concepts
behind Python and e.g. C/C++ is only poorly documented . What else would
be the reason for the over-long discussion in the "Is 'everything' a
refrence or isn't it?" thread in this newsgroup?

From what I know about Python up to now, the problem with the concept
of 'value' in Python is, that it depends ... and it depends on so many
things, that it is hard to give any general valid statement about it
without writing an entire chapter full of details and special cases.

Claudio
 
S

Steve Holden

Claudio Grondi wrote:
[...]
Yes, I know about 'is',

but I mean, that it is not possible to use 'is' as replacement for '=='
operator to achieve in Python same behaviour as it is the case in C and
Javascript when comparing values with '=='.
'is' does the C, Javascript job when comparing lists, but I mean it
fails to give fully predictable results when applied to elements of
lists in case there exist duplicate objects with same 'value' i.e. e.g.
there are two different objects storing the integer value 1, what I mean
can happen when there is enough other code between the Python code lines
assigning the integer value 1 to a list element or any other identifier.

Perhaps you could try again in English? :) Sorry, that's a very complex
sentence and it isn't clear what yo mean.

In C, of course, a == b requires that a and b be of compatible types and
that they have the same value. This means that if they are pointers they
must point to the same thing (which is exactly what "is" tests for).
Or is there in Python a 100% reliable mechanism assuring, that there is
one and _only one_ object carrying a given 'value' (at least for the
built in types as integer, long integer, string, float) and if this
value is to be assigned to a list element or any other literal the
already existing object (if any) will be found and used/referenced?
No more than there is in C or, presumably, Java.

If you want to test for identity, use "is". If you want to test for
equality, use "==". Of you want to test for something else, kindly
explain what you want to test for.

regards
Steve
 
F

Fuzzyman

Claudio Grondi wrote:
[snip..]
Yes, I know about 'is',

but I mean, that it is not possible to use 'is' as replacement for '=='
operator to achieve in Python same behaviour as it is the case in C and
Javascript when comparing values with '=='.
'is' does the C, Javascript job when comparing lists, but I mean it
fails to give fully predictable results when applied to elements of
lists in case there exist duplicate objects with same 'value' i.e. e.g.
there are two different objects storing the integer value 1, what I mean

Hmmm... :
True

Doesn't work with arbitrary longs of course...
can happen when there is enough other code between the Python code lines
assigning the integer value 1 to a list element or any other identifier.
Or is there in Python a 100% reliable mechanism assuring, that there is
one and _only one_ object carrying a given 'value' (at least for the
built in types as integer, long integer, string, float) and if this
value is to be assigned to a list element or any other literal the
already existing object (if any) will be found and used/referenced?

So the Java/C '==' operator sometimes works like '==' in Python and
sometimes works like 'is' ? (It switches between equality and identity
depending on the types being compared IIUC).

My understanding is that you can't use '==' in Java to compare strings,
because it is an identity test not an equality test. You have to use a
string method to compare strings. This bites quite a few people...

Anyway, AFAICT your problem only matters in the abstract (where you are
theoretically comparing objects you haven't specified the type of and
*might* want to use '==' and *might* want to use 'is').

For practical purposes '==' will do what you want, unless you
deliberately create buggy code to cause a problem when you use it...

Unless you can post an example of *non-buggy* code that doesn't behave
how you expect ?

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
 
F

Fuzzyman

Claudio said:
Steve Holden wrote: [snip..]
The problem here is, that I mean, that in Python it makes no sense to
talk about a value of an object, because it leads to weird things when
trying to give a definition what a value of an object is.

You're saying that C and Java get round that problem by sometimes
defining value to mean 'the memory address and object is stored at'.
That hardly seems to clarify what value *really* means, and can lead to
some interesting confusions.

Anyway - for the basic datatypes 'value' seems quite clear. It's only
not clear what this might mean in user defined classes - where value
means whatever you define it to mean.

By overloading the comparison and rich comparison methods of user
defined classes, you have the opportunity to *precisely* define the
meaning of value...
It seems, that in Python there is a lack of operator able to compare
values as it is the case in C and Javascript, simply because in Python
there are no really such things as values, so there is no need to
compare them.

Can you provide an example to clarify what you mean ?

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
 
C

Claudio Grondi

Steve said:
Claudio Grondi wrote:
[...]
Yes, I know about 'is',

but I mean, that it is not possible to use 'is' as replacement for
'==' operator to achieve in Python same behaviour as it is the case in
C and Javascript when comparing values with '=='.
'is' does the C, Javascript job when comparing lists, but I mean it
fails to give fully predictable results when applied to elements of
lists in case there exist duplicate objects with same 'value' i.e.
e.g. there are two different objects storing the integer value 1, what
I mean can happen when there is enough other code between the Python
code lines assigning the integer value 1 to a list element or any
other identifier.


Perhaps you could try again in English? :) Sorry, that's a very complex
sentence and it isn't clear what yo mean.
Here in English ;-) :
a=[1]
.... many other statements here ...
b=[1]
a is b # False
a == b # True
a[0] is b[0] # unpredictable(?)
a[0] == b[0] # True

so a C, Javascript equivalent '==' operator (called here e.g. 'xx')
should in case of code above _always_ give:
a xx b # False
a[0] xx b[0] # True
what becomes only possible if the object holding the integer value 1 is
created only once when a=[1] and reused when executing b=[1].

Claudio
 
F

Fuzzyman

Claudio Grondi wrote:
[snip..]> > Perhaps you could try again in English? :) Sorry, that's a
very complex
sentence and it isn't clear what yo mean.
Here in English ;-) :
a=[1]
... many other statements here ...
b=[1]
a is b # False
a == b # True
a[0] is b[0] # unpredictable(?)
a[0] == b[0] # True

so a C, Javascript equivalent '==' operator (called here e.g. 'xx')
should in case of code above _always_ give:
a xx b # False
a[0] xx b[0] # True
what becomes only possible if the object holding the integer value 1 is
created only once when a=[1] and reused when executing b=[1].

So you're *really* saying that you want this :
 
F

Fuzzyman

Oops... my misreading, sorry.

The reason that, in Python, short ints have the same identity is not
fickle - it's just True. Python creates a new reference (pointer) to
the same object.

You're saying you want one comparison operator that for :
a=[1]
... many other statements here ...
b=[1]

gives the result :
a xx b # False
a[0] xx b[0] # True

What you're saying is that you don't consider a and b equal when they
are container objects of the same type, with the same contents. That's
very counter intuitive.

All the best,


Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
 
S

Steve Holden

Claudio said:
Steve Holden wrote: [...]
The problem here is, that I mean, that in Python it makes no sense to
talk about a value of an object, because it leads to weird things when
trying to give a definition what a value of an object is.
I don;t understand why you say that.
It seems, that in Python there is a lack of operator able to compare
values as it is the case in C and Javascript, simply because in Python
there are no really such things as values, so there is no need to
compare them.
That is simply incorrect. The expression a == b is true under
well-defined circumstances usually referred to as "a and b having the
same value". There *are* such things as values. Presumably since you
know about "is", you also know about "id()". In C Python the id() of an
object is simply its memory address, though that isn't how id() is
defined. The fact remains that each object's id() must be unique at any
point in time (though id()s can be reused).

See. Two different objects with the same value, so they compare equal.

Perhaps the difference you are having problems understanding arises
because Python also defines equality for complex objects.
>>> lst1 = [a, b]
>>> lst2 = [b, a]
>>> lst1 == lst2 True
>>>

Unlike C there is no need to compare each element of the lists:
list.__eq__() automatically iterates over the items of the list, and
returns True only if all pairwise comparisons return True.
The higher level of abstraction/indirection in Python results in making
the concepts of 'value', 'having a value' or 'comparing values' useless,
where it helps in C to express the difference between address and
content at that address and to distinguish between the information
telling _what_ is stored in memory and the information about _where_ it
is stored.
Well in Python each name in a namespace, and each attribute of an
object, and each item in a sequence or a mapping, is a reference to a
value. Where the value is stored is completely irrelevant, and addresses
are only available as an implementation detail in CPython. You can test
if two references are to the same object using "is", which you already
know. In other words

a is b is exactly id(a) == id(b)

Obviously "a is b" implies "a == b", whereas the converse is not true.
It appears to me, that the whole subject of what an identifier in Python
represents and if there is such thingy as 'value' in Python, is not
perfectly well understood even by Python experts programming also in
many other languages and therefore the vital differences in concepts
behind Python and e.g. C/C++ is only poorly documented . What else would
be the reason for the over-long discussion in the "Is 'everything' a
refrence or isn't it?" thread in this newsgroup?
It may so appear to you, but that doesn't make it the case. The reason
for the overly-long discussion is that people insist on picking the
smallest details to bits and arguing over small semantic differences
that are irrelevant to getting programs working.

I have an idea that the people who wrote and maintain the interpreter
find these concepts quite comprehensible, and I don't have any problem
myself. I suspect you are externalising your confusion.
From what I know about Python up to now, the problem with the concept
of 'value' in Python is, that it depends ... and it depends on so many
things, that it is hard to give any general valid statement about it
without writing an entire chapter full of details and special cases.
Well, you really are making something extraordinarily easy much more
difficult than it needs to be. I don't even really understand why you
need a written definition of "what a value is", come to that.

Why don't you write some C that you thing it would be difficult to
rewrite it Python?

There really is no need to be so obsessive about where things are
stored. It simply doesn't matter in a language with no pointer types.

regards
Steve
 
B

bonono

Fuzzyman said:
Claudio said:
Steve Holden wrote: [snip..]
The problem here is, that I mean, that in Python it makes no sense to
talk about a value of an object, because it leads to weird things when
trying to give a definition what a value of an object is.

You're saying that C and Java get round that problem by sometimes
defining value to mean 'the memory address and object is stored at'.
That hardly seems to clarify what value *really* means, and can lead to
some interesting confusions.

Anyway - for the basic datatypes 'value' seems quite clear. It's only
not clear what this might mean in user defined classes - where value
means whatever you define it to mean.
I don't know much about Java but in C, I fail to see any confusion.
There is no such thing as user defined classes nor operator overload.
 
F

Fuzzyman

Fuzzyman said:
Claudio said:
Steve Holden wrote: [snip..]
The problem here is, that I mean, that in Python it makes no sense to
talk about a value of an object, because it leads to weird things when
trying to give a definition what a value of an object is.

You're saying that C and Java get round that problem by sometimes
defining value to mean 'the memory address and object is stored at'.
That hardly seems to clarify what value *really* means, and can lead to
some interesting confusions.

Anyway - for the basic datatypes 'value' seems quite clear. It's only
not clear what this might mean in user defined classes - where value
means whatever you define it to mean.
I don't know much about Java but in C, I fail to see any confusion.
There is no such thing as user defined classes nor operator overload.

You may fail to see the confusion, but feel free to add to it ;-)

The above gentleman is asserting that in *Python* the term value has no
meaning.

I asserted in response :

All the best,


Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
 
P

Peter Hansen

Claudio said:
but I mean, that it is not possible to use 'is' as replacement for '=='
operator to achieve in Python same behaviour as it is the case in C and
Javascript when comparing values with '=='.
'is' does the C, Javascript job when comparing lists, but I mean it
fails to give fully predictable results when applied to elements of
lists in case there exist duplicate objects with same 'value' i.e. e.g.
there are two different objects storing the integer value 1, what I mean
can happen when there is enough other code between the Python code lines
assigning the integer value 1 to a list element or any other identifier.
Or is there in Python a 100% reliable mechanism assuring, that there is
one and _only one_ object carrying a given 'value' (at least for the
built in types as integer, long integer, string, float) and if this
value is to be assigned to a list element or any other literal the
already existing object (if any) will be found and used/referenced?

I think you fundamentally can't get what you want here. It would be
quite possible to implement an optimization on the == operator in Python
which checked whether two items were identical (i.e. "is", the same as
comparing their addresses). This would do just what C is doing in the
case of comparing two lists which are the same, but then the following
code could not be written:
.... def __eq__(self, other):
.... return False
....False

If you eliminate the possibility of writing the above code, you probably
don't have Python any more (or possibly many other very dynamic
languages either).

-Peter
 
B

bonono

Fuzzyman said:
The above gentleman is asserting that in *Python* the term value has no
meaning.
I don't know what he meant and don't want to get into that
value/reference/object thingy discussion as it would be a never ending
thing. I just want to say that '==' in C is very clear to me, whether
it is as useful(correct) as in python or C++ or other higher level
language is another issue. But what would be the interesting confusion
that you envision ?
 
F

Fuzzyman

Ok... so I'm now assuming that the information about '==' provided by
the above gentleman *and* that I understand it correctly.

The only confusion in C (which doesn't have classes) is that two list
(like) objects can't be tested by value - only identity.

In Java, comparing strings using '==' compares for identity not
equality (IIUC), giving *plenty* of room for confusion.

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top