3

I'm frequently finding myself writing repetitive-feeling code in the style below (as it happens, inside a Django settings.py, but the question is meant much more generally):

STACKEXCHANGE_CLIENT_ID = os.getenv('STACKEXCHANGE_CLIENT_ID')
STACKEXCHANGE_CLIENT_SECRET = os.getenv('STACKEXCHANGE_CLIENT_SECRET')
# et cetera

Naturally there are plenty of occasions where I don't want my local variable name to match the name of the environment variable, but it's happening enough that I'm wondering if there's a nice way to avoid the name duplication.

The below code works for me:

_locals = locals()
def f(x):
    _locals[x] = os.getenv(x)

f('TERM')

print TERM

but I have no intention of using this in production, as, to quote the Python documentation on locals():

Note: The contents of this dictionary should not be modified;

so I'm wondering if there exists a valid "supported"/"approved" solution, and if so, what it might look like?

Kristian Glass
  • 37,325
  • 7
  • 45
  • 73

2 Answers2

4

Referencing: How to programmatically set a global (module) variable?

import sys, os

opts = (
    'STACKEXCHANGE_CLIENT_ID', 
    'STACKEXCHANGE_CLIENT_SECRET'
)

module = sys.modules[__name__]
for o in opts:
    setattr(module, o, os.getenv(o))

In the comments of that referenced answer, it links to another that suggests globals() is reliable for updating directly as well...

_g = globals()
for o in opts:
    _g[o] = os.getenv(o)
Community
  • 1
  • 1
jdi
  • 90,542
  • 19
  • 167
  • 203
  • That'd do it, thanks very much - had a hard time trying to find the right vocabulary for what I wanted to do, so totally missed the other question – Kristian Glass Apr 23 '12 at 11:02
0

I guess, it's partly a matter of taste, but I would tend to put these in a dictionary, so:

STACKEXCHANGE_CLIENT_ID = os.getenv('STACKEXCHANGE_CLIENT_ID')
STACKEXCHANGE_CLIENT_SECRET = os.getenv('STACKEXCHANGE_CLIENT_SECRET')

would become:

envars['STACKEXCHANGE_CLIENT_ID'] = os.getenv('STACKEXCHANGE_CLIENT_ID')
envars['STACKEXCHANGE_CLIENT_SECRET'] = os.getenv('STACKEXCHANGE_CLIENT_SECRET')

Or, you could just use the os.environ dictionary directly.

snim2
  • 4,004
  • 27
  • 44
  • This would totally work in a general case. Unfortunately the OP mentions the settings.py of a django project which is expecting them to be global variables. Kinda has him by the ghoulies on this one. – jdi Apr 23 '12 at 01:01
  • Yeah I was perhaps insufficiently clear with my requirements, I just didn't want it to be interpreted too narrowly as a Django-related question, but the global-ness is definitely a requirement; thanks though – Kristian Glass Apr 23 '12 at 11:04