3

I have a class with static variables for error/status code lookup. Take HTTP status code as example

class Foo(object):
    OK = 200
    Not_Modified = 304
    Forbidden = 403
    Internal_Server_Error = 500

Now I need to retrieve the verbal status ('OK', 'Not_Modified', etc) base on the code (200, 403, etc). I can't modify the structure of the class since other programs are using it. So I created a dictionary description_by_val that contain the {code : description}:

from collections import Hashable

class Foo(object):
    OK = 200
    Not_Modified = 304
    Forbidden = 403
    Internal_Server_Error = 500
    description_by_val = dict((value, key)
        for key, value in locals().iteritems()
            if not key.startswith("__") and value and isinstance(value, Hashable))


>>> Foo.description_by_val[200]
'OK'

Now I have questions in terms of performance and code practice.

  • Every time I call Foo.description_by_val will it cause the dictionary be regenerated? this is not good even the data set is very small, because this will get call millions times.
  • It that approach simply bad practice? I don't want to manually create the dictionary by hand and I think it should be a static variable.

any thought?

update:

My colleague just pointed out to me that I could print something during the creation of description_by_val to find out if it will be regenerated.

>>> from collections import Hashable
>>> 
>>> def show(key):
...     print key
...     return True
... 
>>> 
>>> class Foo(object):
...     OK = 200
...     Not_Modified = 304
...     Forbidden = 403
...     Internal_Server_Error = 500
...     description_by_val = dict((value, key)
...         for key, value in locals().iteritems()
...             if not key.startswith("__") and key and isinstance(value, Hashable) and show(key))
... 
OK
Forbidden
Internal_Server_Error
Not_Modified
>>> 
>>> Foo.description_by_val
{200: 'OK', 304: 'Not_Modified', 403: 'Forbidden', 500: 'Internal_Server_Error'}
>>> Foo.description_by_val
{200: 'OK', 304: 'Not_Modified', 403: 'Forbidden', 500: 'Internal_Server_Error'}
>>> Foo.description_by_val[200]
'OK'

I'm now happy with that I don't have to worry about the performance. I want to find out why it behave like this :)

wilson
  • 177
  • 1
  • 7

1 Answers1

4

Your idea is sound. The dictionary is not regenerated every time, only the first time it is created. Lookup is efficient and reliable, and this is unlikely to cause problems that I can see. Using this kind of reverse dictionary is pretty common, and you have the isinstance(value, Hashable) check in a good place as well. You should be fine.

-- Edited --

Your code is fine, I just missed the trailing paren.

g.d.d.c
  • 46,865
  • 9
  • 101
  • 111