|
|
|
|
|
|
| Author |
Message |
Steven D'Aprano *nix forums Guru
Joined: 07 May 2005
Posts: 1020
|
Posted: Sat Dec 24, 2005 1:59 am Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
On Fri, 23 Dec 2005 23:51:22 +0200, Max wrote:
| Quote: | Steven D'Aprano wrote:
They certainly don't look much further from being integers than
booleans do.
You think?
hamburger, steak, fish, chicken, pizza
What meaning do you give to steak**fish? Should that meaning change if I
happened to have written pizza first instead of last?
What meaning do you give to True**False?
|
Given that True == 1 and False == 0 in Python (which in my opinion is
unfortunate), then it is obviously 1.
True booleans don't support arithmetic operators like **, and neither
should enums.
--
Steven. |
|
| Back to top |
|
 |
Max *nix forums addict
Joined: 17 Mar 2005
Posts: 74
|
Posted: Fri Dec 23, 2005 9:51 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
Steven D'Aprano wrote:
| Quote: |
They certainly don't look much further from being integers than
booleans do.
You think?
hamburger, steak, fish, chicken, pizza
What meaning do you give to steak**fish? Should that meaning change if I
happened to have written pizza first instead of last?
|
What meaning do you give to True**False?
| Quote: |
The fact that they can be counted shouldn't fool you into thinking they
are numbers.
|
--Max |
|
| Back to top |
|
 |
Bengt Richter *nix forums Guru
Joined: 25 Feb 2005
Posts: 711
|
Posted: Tue Dec 20, 2005 2:37 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
On Tue, 20 Dec 2005 09:16:03 +1100, Ben Finney <bignose+hates-spam@benfinney.id.au> wrote:
| Quote: | eswald@gmail.com writes:
Ben Finney wrote:
Is there some behaviour other than "evaluate to False" or "raise an
exception", that could indicate "not comparable"?
Yes: return NotImplemented. Note that the == operator automagically
returns False in this case.
"spam".__eq__("spam")
True
"spam".__eq__("ham")
False
"spam".__eq__(23)
NotImplemented
This way, the user could explicitly call __eq__ and check for
NotImplemented if he desires the exceptional behavior.
Thanks, I was unaware of the standard usage of NotImplemented. That
seems like a sensible solution.
URL:http://docs.python.org/ref/types.html#l2h-29
OTOH, that says the truth value is True, so this does not fail: |
| Quote: | assert 'spam'.__eq__(23)
|
Which seems counterintuitive. The explicit value test
| Quote: | assert 'spam'.__eq__(23) is NotImplemented
|
would succeed irrespective of truth value,
but it seems contorted and unpythonic to have to write
| Quote: | assert 'spam'.__eq__(23) is False
Traceback (most recent call last): |
File "<stdin>", line 1, in ?
AssertionError
to get the effect you might naively expect from
| Quote: | assert 'spam'.__eq__(23)
|
I wonder what the rationale for the NotImplemented True truth value was, as opposed to False.
On the third hand, I recently posted an idea of using NotImplemented
as a (handy because predefined) logically true sentinel value to return
from a test function to distinguish not_applicable from applicable_and_ok
when desired, yet allowing assert testfun(...) to succeed either way.
That code would have to use another boolishly True sentinel if NotImplemented
were changed to have False truth value.
Maybe it would be useful to have a couple of builtin sentinels like TrueSentinel
and FalseSentinel (or sentinel_t and sentinel_f or pick some names so we
wouldn't be tempted to misuse unique builtins like NotImplemented and Exception etc.
Regards,
Bengt Richter |
|
| Back to top |
|
 |
Ben Finney *nix forums Guru Wannabe
Joined: 10 May 2005
Posts: 240
|
Posted: Mon Dec 19, 2005 10:16 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
eswald@gmail.com writes:
| Quote: | Ben Finney wrote:
Is there some behaviour other than "evaluate to False" or "raise an
exception", that could indicate "not comparable"?
Yes: return NotImplemented. Note that the == operator automagically
returns False in this case.
"spam".__eq__("spam")
True
"spam".__eq__("ham")
False
"spam".__eq__(23)
NotImplemented
This way, the user could explicitly call __eq__ and check for
NotImplemented if he desires the exceptional behavior.
|
Thanks, I was unaware of the standard usage of NotImplemented. That
seems like a sensible solution.
<URL:http://docs.python.org/ref/types.html#l2h-29>
--
\ "My doctor told me to stop having intimate dinners for four. |
`\ Unless there are three other people." -- Orson Welles |
_o__) |
Ben Finney |
|
| Back to top |
|
 |
eswald@gmail.com *nix forums beginner
Joined: 19 Dec 2005
Posts: 1
|
Posted: Mon Dec 19, 2005 6:03 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
Ben Finney wrote:
| Quote: | Antoon Pardon wrote:
I just downloaded your enum module for python [from the Cheeseshop]
and played a bit with it. IMO some of the behaviour makes it less
usefull.
[...]
I also think it would be more usefull if enums from different
enumerations just tested unequal.
[...]
However, I'm aware that this is not how other Python types behave:
23 == 23
True
42 == 23
False
"spam" == 23
False
Is there a semantic difference between these cases? Is that difference
enough to want different behaviour?
Is there some behaviour other than "evaluate to False" or "raise an
exception", that could indicate "not comparable"?
|
Yes: return NotImplemented. Note that the == operator automagically
returns False in this case.
| Quote: | "spam".__eq__("spam")
True
"spam".__eq__("ham")
False
"spam".__eq__(23)
NotImplemented |
This way, the user could explicitly call __eq__ and check for
NotImplemented if he desires the exceptional behavior.
- Eric |
|
| Back to top |
|
 |
Steven D'Aprano *nix forums Guru
Joined: 07 May 2005
Posts: 1020
|
Posted: Mon Dec 19, 2005 2:41 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
On Mon, 19 Dec 2005 05:30:11 -0800, Ben Sizer wrote:
| Quote: | Enums are not conceptually subclasses of integers. Integers just happen to
be a useful method to implement enumerations.
Aren't they? They have discrete values, can be ordered and compared for
equality, etc.
|
Just like:
mammal, reptile, amphibian, bird, fish
They are discrete values, they can be ordered in many different ways
(alphabetically, by biological clade, by average number of genes, etc),
and compared for equality (fish is not bird). But they aren't numbers.
It is true that you can create a one-to-one mapping from integers to
enums, but then you can also create a one-to-one mapping from William
Shakespeare's sonnets to enums. That second implementation is,
unfortunately, rather impractical.
| Quote: | I think the 'numerate' part of 'enumeration' is a hint
here.
|
It certainly is a hint, but not of what you think. It means they are
countable, not that they are numbers. You could try looking "enumerate"
up in the dictionary: it means to count, as in "by the time she finished
enumerating all my flaws, I felt three inches high".
| Quote: | They certainly don't look much further from being integers than
booleans do.
|
You think?
hamburger, steak, fish, chicken, pizza
What meaning do you give to steak**fish? Should that meaning change if I
happened to have written pizza first instead of last?
The fact that they can be counted shouldn't fool you into thinking they
are numbers.
--
Steven. |
|
| Back to top |
|
 |
Ben Sizer *nix forums addict
Joined: 01 Mar 2005
Posts: 93
|
Posted: Mon Dec 19, 2005 1:30 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
Steven D'Aprano wrote:
| Quote: | On Fri, 16 Dec 2005 02:43:35 -0800, Ben Sizer wrote:
Is it possible to make it have the following sort of behaviour? :
ShirtSize.small == AppleSize.small
True
Okay, so I was wrong to say that nobody was seriously suggesting that sort
of behaviour.
|
I was working under what looks to have been an incorrect assumption
that someone was looking for a way to do the above. After all, it was
mentioned in what seemed like seriousness. I can't think of a use case
for it, myself.
| Quote: | It works for comparing a boolean (True) vs. an integer (1), so it has
some sort of precedent. (Especially if you make the tenuous assumption
that True,False are language-supported 'enums' for 0 and 1.)
Enums are not conceptually subclasses of integers. Integers just happen to
be a useful method to implement enumerations.
|
Aren't they? They have discrete values, can be ordered and compared for
equality, etc. I think the 'numerate' part of 'enumeration' is a hint
here. They certainly don't look much further from being integers than
booleans do. But, if nobody actually needs the behaviour I described
before, this point is irrelevant.
--
Ben Sizer |
|
| Back to top |
|
 |
Ben Finney *nix forums Guru Wannabe
Joined: 10 May 2005
Posts: 240
|
Posted: Sat Dec 17, 2005 12:42 am Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
"Ben Sizer" <kylotan@gmail.com> writes:
| Quote: | Transitivity within any single enumeration plus transivity of
equivalence across multiple enumerations, should be enough for most
needs, no?
|
+1 to transitivity within an enumeration. -1 to transitivity across
enumerations. If they're supposed to be equivalent, why are you
separating them into different enumerations at all?
The whole point of an enumeration, as I see it, is to have a set of
values that are only meaningfully equal or sequenced within that
enumeration.
--
\ "You've got the brain of a four-year-old boy, and I'll bet he |
`\ was glad to get rid of it." -- Groucho Marx |
_o__) |
Ben Finney |
|
| Back to top |
|
 |
Ben Finney *nix forums Guru Wannabe
Joined: 10 May 2005
Posts: 240
|
Posted: Sat Dec 17, 2005 12:37 am Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
Paul Rubin <http://phr.cx@NOSPAM.invalid> writes:
| Quote: | All in all, comparing by object identity doesn't sound too good.
Maybe you want to have the enum contain its own name internally, and
do a string comparison.
|
The "__eq__ compares identity" was a glib pseudo-implementation; I
didn't think it through. The existing 'enum' implementation doesn't
use identity, and future ones won't either.
The intended meaning was more like:
class EnumValue(object):
# ...
def __eq__(self, other):
result = compare_attribute_values(self, other)
return result
In other words, identity doesn't matter, but every value from every
enumeration will compare inequal to each other. If an EnumValue
instance is copied, the copies will compare equal.
--
\ "Remember men, we're fighting for this woman's honour; which is |
`\ probably more than she ever did." -- Groucho Marx |
_o__) |
Ben Finney <http://www.benfinney.id.au/> |
|
| Back to top |
|
 |
Steven D'Aprano *nix forums Guru
Joined: 07 May 2005
Posts: 1020
|
Posted: Sat Dec 17, 2005 12:23 am Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
On Fri, 16 Dec 2005 02:43:35 -0800, Ben Sizer wrote:
| Quote: | Ben Finney wrote:
The problem with "is the same value" as an explanation for '==' is
that it doesn't help in cases such as::
ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')
What should be the result of this comparison::
ShirtSize.small == AppleSize.small
Are they "the same value"? They're both "small" (and they both coerce
to the same string value, and in this case the same integer value).
Is it possible to make it have the following sort of behaviour? :
ShirtSize.small == AppleSize.small
True
|
Okay, so I was wrong to say that nobody was seriously suggesting that sort
of behaviour.
| Quote: | It works for comparing a boolean (True) vs. an integer (1), so it has
some sort of precedent. (Especially if you make the tenuous assumption
that True,False are language-supported 'enums' for 0 and 1.)
|
Enums are not conceptually subclasses of integers. Integers just happen to
be a useful method to implement enumerations.
--
Steven. |
|
| Back to top |
|
 |
Steven D'Aprano *nix forums Guru
Joined: 07 May 2005
Posts: 1020
|
Posted: Sat Dec 17, 2005 12:17 am Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
On Fri, 16 Dec 2005 19:45:51 +1100, Ben Finney wrote:
| Quote: | The problem with "is the same value" as an explanation for '==' is
that it doesn't help in cases such as::
ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')
What should be the result of this comparison::
ShirtSize.small == AppleSize.small
Are they "the same value"? They're both "small" (and they both coerce
to the same string value, and in this case the same integer value).
|
I don't think anyone seriously intends to argue that ShirtSize.small
should test equal to AppleSize.small.
| Quote: | If not, is 'False' the right way to indicate that?
|
Why not? The intuitive answer is that they are "not equal".
In the case of apples and shirts, the intuitive answer can be misleading
because if you had a small enough shirt (say, for a Barbi doll) one might
be tempted to say "Yes, they are the same size".
A better example might be StringLength.long == BookSize.long. Both coerce
to the same string, but one measures physical length and the other
measures number of words. They are incompatible measures, and can't be
ordered. A strict physicist might argue that asking "is five kilograms
equal to three metres?" is a nonsensical question, but that's not the
Python way.
(And an even better physicist will answer that kilograms and metres can
not only be tested for equality, but can be ordered -- there are
mathematical transformations, common in relativistic physics, where all
physical quantities including time and mass, are transformed into lengths.
These physicists calculated *everything* in terms of dimensionless values
and multiples of length, length squared, length cubed, etc.)
| Quote: | Or is it an error to even try comparing them?
|
Perhaps there are unusual cases where comparing strings and ints for
equality should be an error. There may even be unusual cases where
comparing ints and floats should be an error. But I don't believe that
this should be the default behaviour, and it isn't the Python way.
Likewise for enums from different enumerations. By default they should
evaluate unequal, not raise an exemption.
--
Steven. |
|
| Back to top |
|
 |
Steven D'Aprano *nix forums Guru
Joined: 07 May 2005
Posts: 1020
|
Posted: Fri Dec 16, 2005 11:44 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
On Thu, 15 Dec 2005 23:53:36 -0500, Peter Hansen wrote:
| Quote: | Ben Finney wrote:
These are valid concerns. I can't see how to reconcile these against
the desire for values from different enums to fail comparison.
Am I alone in my tri-state view of enumeration value comparisons? Can
anyone else defend why values from different enumerations should not
compare?
While I'm largely a disinterested bystander, it occurs to me that if you
look at the reasons behind wanting enumerations in the first place, you
might find a good reason to defend this view.
For example, if enumerations are intended to reduce the likelihood of
certain types of errors (where the use of typical XXXX=3 "constants"
might be more prone to errors), then perhaps this suggests that passing
errors silently is bad. That is, trying to compare enumerations that
should not be compared *is* an error (raising an exception) *because*
the whole point of enumerations is to avoid errors in such cases.
|
In my opinion, rather than make all enums fail equality testing, two
better solutions would be:
(1) sub-class Enum to have StrictEnum. Enum allows equality testing for
normal Pythonic behaviour. StrictEnum fails equality testing for extra B&D
behaviour.
(2) Expect the user to make an explicit test when they want the stricter
testing. At the moment two different enumerations have the same class, but
Ben could (perhaps) hash the enumeration values to get a unique ID that
distinguishes one enumeration from another. Or some other strategy that
would allow something like:
if value.from_same_enumeration(other) and value == other
for value and other both enums.
Of the two, I suspect that (1) is far less work for both Ben and the
people using his class, although for introspection purposes it might be
nice to have some sort of unique enumeration ID. That could even be
something as simple as a tuple of the enumeration values.
--
Steven. |
|
| Back to top |
|
 |
Steven D'Aprano *nix forums Guru
Joined: 07 May 2005
Posts: 1020
|
Posted: Fri Dec 16, 2005 11:31 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
On Fri, 16 Dec 2005 15:16:08 +1100, Ben Finney wrote:
| Quote: | As can be seen from the above, you raise an exception when one wants
to compare Enums from different enumarations, but it seems a bit
strange that different enumerations belong to the same type.
This does seem a point that could be confusing. Would it be better if
every Enum instance had its own unique subclass of EnumValue, that was
used to instantiate values for that enumeration?
|
That seems to be creating complication for its own sake.
| Quote: | I also think it would be more usefull if enums from different
enumerations just tested unequal.
My rationale for this is: The only purpose of an enumeration is to
have a set of arbitrary unique values within that enumeration. The
values make no sense in the context of a different enumeration, so I
see three different comparison results:
Weekday.mon == Weekday.mon
True
Weekday.fri == Weekday.mon
False
Colour.blue == Weekday.mon
[...]
enum.EnumValueCompareError: Not values from the same enumeration
However, I'm aware that this is not how other Python types behave:
23 == 23
True
42 == 23
False
"spam" == 23
False
Is there a semantic difference between these cases? Is that difference
enough to want different behaviour?
|
I don't believe so.
It seems reasonable to me for other comparisons such as __lt__ etc.
to fail unless the objects belong to the same enumeration. But equality
and inequality are special. Unordered objects support equality testing.
The question whether Mohammad is greater than or less than the mountain
has no answer, because we don't know how to order the two (by height? by
mass? by religious belief? by economic value? by importance to human
history?). But we can certainly answer the question is Mohammad equal to
the mountain -- the answer is certainly no, no matter how we order them.
| Quote: | Because as it is you can't put elements from different enumerations
in a list and check with the in operator if a specific enum value is
in the list.
It could also cause problems for dictionaries, since keys in
dictionaries can be tested against a key giving in a subscription.
These are valid concerns. I can't see how to reconcile these against
the desire for values from different enums to fail comparison.
|
Perhaps you are just being over-strict -- soon you'll be writing in Pascal
:-)
Failing order comparisons is reasonable, but why refuse to test for
equality? If you ask "is Monday equal to Blue?" the intuitive answer is
"no", not "my brain just crashed trying to evaluate the answer!".
--
Steven. |
|
| Back to top |
|
 |
Mike Meyer *nix forums Guru
Joined: 21 Feb 2005
Posts: 1044
|
Posted: Fri Dec 16, 2005 4:28 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
Ben Finney <bignose@polar.local> writes:
| Quote: | Mike Meyer <mwm@mired.org> writes:
Peter Hansen <peter@engcorp.com> writes:
That is, [perhaps] trying to compare enumerations that should not
be compared *is* an error (raising an exception) *because* the
whole point of enumerations is to avoid errors in such cases.
Except it might not be an error. For instance, if I've got a list of
enum objects taken from various types (say I've got one set of enums
for days of the week, another for months of the year, and so on, and
which I use depends on whether the user wants to select days of the
week, months of the year, etc), it makes perfect sense to want to know
if a specific enum value is in the list, and the obvious way to check
it is with "my_value in enum_list". That won't work if you raise an
exception - it takes a relatively convoluted bit of code to make this
test.
What's being discussed here is what happens when comparing the *values*
from the enumeration.
|
That's what I thought I was discussing, but apparently I wasn't clear
enough. Let me try again.
I think it's perfectly reasonable to store enum values from different
enums in a list, and check for a specific value being in that list. If
comparing two enum values can raise an exception, then doinng this
become problematic, as you may get an exception. According to what you
say below, this isn't true for any builtin type or any type in the
standard library.
| Quote: | Python generally uses '==' to mean "is the same value". To do that,
a simple true/false return is enough. In raising an exception,
you're making '==' carry an extra meaning (I'm not sure *what* that
is, though).
The problem with "is the same value" as an explanation for '==' is
that it doesn't help in cases such as::
ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')
|
Actually, it provides a very explicit guideline for these cases. The
guidelines is by no means obvious, as witness languages like LISP,
which have multiple equality operators.
| Quote: | What should be the result of this comparison::
ShirtSize.small == AppleSize.small
Are they "the same value"? They're both "small" (and they both coerce
to the same string value, and in this case the same integer value).
|
That depends on the semantics you want to place on the values of
enums. Reasonable arguments can be made for anything from "they're
exactly like small integers" to "the values are an implementation
detail, and you shouldn't worry about them." That they coerce to the
same string is irreleevant, at least in python, which doesn't coerce
strings to
| Quote: | Do any python builtins behave that way? How about anything in the
python standard library?
No to both; I believe this may be a defining property of
enumerations. Am I wrong?
|
There are enum implementations that don't treat comparing enum values
from different enums as an error, so I'd say you're wrong. In Python's
case, comparing two objects for identity never raises an exception for
any type that comes with the language, so I'd say that that was a
defining property of python.
<mike
--
Mike Meyer <mwm@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. |
|
| Back to top |
|
 |
Skip Montanaro *nix forums Guru
Joined: 28 Feb 2005
Posts: 403
|
Posted: Fri Dec 16, 2005 3:37 pm Post subject:
Re: Enumeration idioms: Values from different enumerations
|
|
|
| Quote: | ShirtSize = Enum('small', 'medium', 'large')
AppleSize = Enum('small', 'large')
|
Ben> What should be the result of this comparison::
| Quote: | ShirtSize.small == AppleSize.small
|
False. They are values from different objects. Just make __eq__ map to
"is". I think you'll be fine.
Ben> Or is it an error to even try comparing them?
As someone else pointed out containment tests become difficult with your
current formulation.
| Quote: | Do any python builtins behave that way? How about anything in the
python standard library?
|
Ben> No to both; I believe this may be a defining property of
Ben> enumerations. Am I wrong?
I think so. <0.5 wink>. I think you should be able to compare any two
objects. I think the complex types give you a little wiggle room on the
size comparisons (<, <=, >, >=), but I think == and != really ought to work.
Skip |
|
| Back to top |
|
 |
Google
|
|
| Back to top |
|
 |
|
|
The time now is Tue Jan 06, 2009 7:21 pm | All times are GMT
|
|
Credit Counseling | Learn real Kung Fu | Loan | Credit Cards | Loans
|
|
Copyright © 2004-2005 DeniX Solutions SRL
|
|
|
|
Other DeniX Solutions sites:
Unix/Linux blog |
electronics forum |
medicine forum |
science forum |
|
|
Privacy Policy
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|