newbie question

Dan Bishop danb_83 at yahoo.com
Sun Dec 19 09:33:41 EST 2004


David Wurmfeld wrote:
> I am new to python; any insight on the following would be
appreciated, even
> if it is the admonition to RTFM (as long as you can direct me to a
relevant
> FM)

http://www.python.org/doc/

> Is there a standard approach to enumerated types? I could create a
> dictionary with a linear set of keys, but isn't this overkill? There
is
> afterall a "True" and "False" enumeration for Boolean.

If you're lazy, you can just use ints, like the "calendar" module did
for the weekday names:

MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2
THURSDAY = 3
FRIDAY = 4
SATURDAY = 5
SUNDAY = 6

This can be more concisely written as:

MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY =
xrange(7)

If you want an enumeration like bool where printing an enumeration
value prints its name instead of the int, you can do something like:

class Weekday(int):
_NAMES = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Saturday', 'Sunday')
def __repr__(self):
return Weekday._NAMES[self]

# Monday = Weekday(0); Tuesday = Weekday(1); etc.
for i, dayName in enumerate(Weekday._NAMES):
globals()[dayName] = Weekday(i)

If you'd rather refer to the names as, e.g., "Weekday.Monday", you can
use setattr(Weekday, dayName, Weekday(i))

If you have multiple enum classes to write, you can do:

def enum(*names):
class Enum(int):
_NAMES = names
def __repr__(self):
return Enum._NAMES[self]
for i, name in enumerate(names):
setattr(Enum, name, Enum(i))
return Enum

Weekday = enum('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Saturday', 'Sunday')
Sex = enum('Female', 'Male')

> Is there a way to ignore case in string comparisons? I want 'Oranges'
to
> equal 'oranges' when using the evaluation operator (==). I don't care
about
> string inequalities (<, >)

s1.lower() == s2.lower()

> If I am compelled to use dictionaries for enumerated types, is there
a way
> to generate unique keys automatically: something like
> "myDict.appendWithAutoKey("Persimmons")"?
>
> Is there a way to overload operators to accommodate an enumeration?

There's a way to overload operators for any class, not just
enumerations.  See http://docs.python.org/ref/specialnames.html, and
pay special attention to section 3.3.7.  For operations that don't make
sense, you can "return NotImplemented" or "raise TypeError()"

> Finally, (for now at least) consider the following list.
>
> myList = [apple, 13, plum, cherry, 'Spam', tomato, 3.35]
>
> Exactly how does the "for x in myList" work?

It works as if you had written:

for _i in xrange(len(myList)):
x = myList(_i)
...

> If the list is a heterogeneous list of disparate types, the ==
operator
> works fine, independent of type.
> For example, (if x == 'spam') evaluates as false if the item in the
list is
> an integer. But if I try to do this: (if x.__abs()__) throws an
exception

It should always raise an exception.  Perhaps you meant "if abs(x)", in
which case you can just write "if x", which is equivalent in any class
that correctly implements __abs__ and __nonzero__.  If you meant to
test whether x.__abs__ exists, you can use "if hasattr(x, '__abs__')".

> if
> x "pulls" a non integer from the list. Wouldn't you think that an
iterative
> would have the "sense" to understand that in this limited scope if a
method
> didn't apply to the iterator just "fail" (i.e. evaluate to False) the

> evaluation and move along?

No, for the same reason that 17 + 'x' should not just evaluate to False
and move along.

> Do I have to manually interrogate each iteration
> for the proper type before I test?

If the operations you want to use don't apply to all of your data, then
they probably shouldn't be in the same list.

> Think about it; the interpreter has to evaluate disparate types for
> equality. How exactly does the it "know" that for this iteration, x
is an
> integer,

Because type(x) == int.

> and the evaluation (if x == 'spam') is False,

It looks for the methods __eq__ and __cmp__ for the left-side object,
in that order.  If neither is implemented, it looks at the right side.

> and doesn't throw an exception for a type mismatch?

Originally, for technical reasons, comparisions couldn't throw
exceptions at all, which is why the built-in types define meaningless
comparisons like

>>> 2004 < 'spam'
1
>>> [] < {}
0

For ==, the reasoning is that equality implies comparibility, and
contrapositively, if two objects aren't even comparable they aren't
equal.




More information about the Python-list mailing list