(original) (raw)

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 )