[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

best way to have enum-like identifiers?

Mark Harrison

3/12/2008 4:53:00 AM

I currently have a 2-dim hash, indexed by two strings:

template['py']['funcpre']
template['py']['funcpost']
...

but I would prefer to have these indexed by constants of
some kind, since this seems a bit more natural:

template[py][funcpre]
template[py][funcpost]
...

Currently I'm just putting this at the top of the file:

py=1
funcpre=2
funcpost=3
...

but I'm curious if there's a better way of doing this,
some kind of enum-like thing or somesuch.

Many TIA!
Mark

--
Mark Harrison
Pixar Animation Studios
5 Answers

Ben Finney

3/12/2008 6:01:00 AM

0

mh@pixar.com writes:

> Currently I'm just putting this at the top of the file:
>
> py=1
> funcpre=2
> funcpost=3
> ...

Slightly better is:

py = object()
funcpre = object()
funcpost = object()

Thus, those names are all bound to unique objects, that won't be
unexpectedly duplicated by some other value.

> but I'm curious if there's a better way of doing this, some kind of
> enum-like thing or somesuch.

Please try the 'enum' package in the Cheeseshop:

<URL:http://pypi.python.org/pyp...

--
\ â??When a well-packaged web of lies has been sold to the masses |
`\ over generations, the truth will seem utterly preposterous and |
_o__) its speaker a raving lunatic.â? â??Dresden James |
Ben Finney

Aaron Brady

3/12/2008 6:30:00 AM

0

> > [enums snip]
> Thus, those names are all bound to unique objects, that won't be
> unexpectedly duplicated by some other value.
>
> > but I'm curious if there's a better way of doing this, some kind of
> > enum-like thing or somesuch.
>
> Please try the 'enum' package in the Cheeseshop:

Am I the only one superstitious about putting identifiers in strings?

>  When a well-packaged web of lies has been sold to the masses
... someone sold them.

>>> c= type('Enum',(),{})
>>> [ setattr( c, v, object() ) for v in 'py funcpre funcpost'.split() ]
[None, None, None]
>>> c.funcpost
<object object at 0x00A37478>
>>> c.funcpre
<object object at 0x00A37470>

You don't need them to be ints or anything, do you, like USER_BASE+ 1?

Peter Otten

3/12/2008 8:53:00 AM

0

mh@pixar.com wrote:

> I currently have a 2-dim hash, indexed by two strings:
>
> template['py']['funcpre']
> template['py']['funcpost']
> ...
>
> but I would prefer to have these indexed by constants of
> some kind, since this seems a bit more natural:
>
> template[py][funcpre]
> template[py][funcpost]
> ...
>
> Currently I'm just putting this at the top of the file:
>
> py=1
> funcpre=2
> funcpost=3
> ...
> but I'm curious if there's a better way of doing this,
> some kind of enum-like thing or somesuch.

A dictionary with a fixed set of keys is better spelt as a class, e. g.
instead of the inner dictionary you can use something like

class Hooks(object):
def __init__(self, pre=None, post=None):
self.pre = pre
self.post = post

....
def before(): print "before"
def after(): print "after"

template["py"] = Hooks(before, after)

Peter

Pete Forman

3/12/2008 5:35:00 PM

0

mh@pixar.com writes:

> Currently I'm just putting this at the top of the file:
>
> py=1
> funcpre=2
> funcpost=3
> ...

That can be done more compactly with

py, funcpre, funcpost = range(3)

give or take 1.


> but I'm curious if there's a better way of doing this,
> some kind of enum-like thing or somesuch.

https://launchpad.... describes itself as yet another Python
enum implementation. Its author is Barry Warsaw.
--
Pete Forman -./\.- Disclaimer: This post is originated
WesternGeco -./\.- by myself and does not represent
pete.forman@westerngeco.com -./\.- the opinion of Schlumberger or
http://petef... -./\.- WesternGeco.

Tim Chase

3/12/2008 7:13:00 PM

0

>> Currently I'm just putting this at the top of the file:
>> py=1
>> funcpre=2
>> funcpost=3
>> ...
>
> That can be done more compactly with
>
> py, funcpre, funcpost = range(3)

I've harbored a hope that a combination of PEP 3132[1] ("Extended
Iterable unpacking") and itertools.count()[2] would be available
for doing something like this:

py, funcpre, funcpost, *unexhausted_iterator = count()

which would theoretically allow me to just add new enum names to
the LHS without having to update constant passed to range() on
the RHS.

Unfortunately, it looks like this wasn't a desirable behavior
because the PEP describes the "*unexhausted_iterator" notation
unpacking as a list, not as an iterable.

My desired syntax would work well for bit-mask fields as well:

def bit_iter(i=0):
assert i >= 0
while True:
yield 1 << i
i += 1
read, write, execute, *_ = bit_iter()

and I'm sure there are other use-cases I've not yet considered.

Diez Roggisch hacked together a disturbingly (in the "that hurts
my brain to sniff the stack" way) beautiful/functional
decorator[3] that does something like this in Python2.4+ and can
just be used something like

@variably_unpack
def just_enough(): return itertools.count()
read, write, execute = just_enough()

which is a fabulous syntax, IMHO.

-tkc

[1]
http://www.python.org/dev/peps...

[2]
http://docs.python.org/dev/library/itertools.html#itert...

[3]
http://groups.google.com/group/comp.lang.python/browse_thread/thread/63dce474e196adac/d98522d9bedae946#d98522...