[Python-Dev] constant/enum type in stdlib

Glenn Linderman v+python at g.nevcal.com
Thu Nov 25 10:34:51 CET 2010


So the following code defines constants with associated names that get 
put in the repr.

I'm still a Python newbie in some areas, particularly classes and 
metaclasses, maybe more.
But this Python 3 code seems to create constants with names ... works 
for int and str at least.

Special case for int defines a special  __or__ operator to OR both the 
values and the names, which some might like.

Dunno why it doesn't work for dict, and it is too late to research that 
today.  That's the last test case in the code below, so you can see how 
it works for int and string before it bombs.

There's some obvious cleanup work to be done, and it would be nice to 
make the names actually be constant... but they do lose their .name if 
you ignorantly assign the base type, so at least it is hard to change 
the value and keep the associated .name that gets reported by repr, 
which might reduce some confusion at debug time.

An idea I had, but have no idea how to implement, is that it might be 
nice to say:

     with imported_constants_from_module:
            do_stuff

where do_stuff could reference the constants without qualifying them by 
module.  Of course, if you knew it was just a module of constants, you 
could "import * from module" :)  But the idea of with is that they'd go 
away at the end of that scope.

Some techniques here came from Raymond's namedtuple code.


def constant( name, val ):
     typ = str( type( val ))
     if typ.startswith("<class '")  and  typ[ -2: ] == "'>":
         typ = typ[ 8:-2 ]
     ev = '''
class constant_%s( %s ):
     def __new__( cls, val, name ):
         self = %s.__new__( cls, val )
         self.name = name
         return self
     def __repr__( self ):
         return self.name + ': ' + str( self )
'''
     if typ == 'int':
         ev += '''
     def __or__( self, other ):
         if isinstance( other, constant_int ):
             return constant_int( int( self ) | int( other ),
                                  self.name + ' | ' + other.name )
'''
     ev += '''
%s = constant_%s( %s, '%s' )

'''
     ev = ev % ( typ, typ, typ, name, typ, repr( val ), name )
     print( ev )
     exec( ev, globals())

constant('O_RANDOM', val=16 )

constant('O_SEQUENTIAL', val=32 )

constant("O_STRING", val="string")

def foo( x ):
     print( str( x ))
     print( repr( x ))
     print( type( x ))

foo( O_RANDOM )
foo( O_SEQUENTIAL )
foo( O_STRING )

zz = O_RANDOM | O_SEQUENTIAL

foo( zz )

y = {'ab': 2, 'yz': 3 }
constant('O_DICT', y )

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20101125/fa5b0dd6/attachment.html>


More information about the Python-Dev mailing list