1

How would I accomplish the following?

>>> x={'NON_EPISODIC_MOVIE': 11}
>>> for k,v in x.items():
...     k=v
... 
>>> NON_EPISODIC_MOVIE
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'NON_EPISODIC_MOVIE' is not defined

Basically, I want to be able to convert a dictionary mapping into the following:

NON_EPISODIC_MOVIE = 11
...other items...

if content_type == NON_EPISODIC_MOVIE:
    # do something

How would this be accomplished from a dict?

David542
  • 104,438
  • 178
  • 489
  • 842
  • 1
    Dynamic variables are almost certainly the wrong approach. What's wrong with doing `if content_type == x['NON_EPISODIC_MOVIE']:`? –  Jan 08 '15 at 03:29
  • What is an integer mapping? It looks like you are trying to make constants... – dursk Jan 08 '15 at 03:29
  • @mattm I'm not sure what the correct term would be for this but setting a name for an integer so it can be more easily recognized (aliasing) ? For example: `MATTM_USER_ID = 3161282` – David542 Jan 08 '15 at 03:31
  • possible duplicate of [Dynamically set local variable in Python](http://stackoverflow.com/questions/8028708/dynamically-set-local-variable-in-python) – Henry Keiter Jan 08 '15 at 03:32
  • 1
    @David542. Do you mean an [enum](https://docs.python.org/3/library/enum.html#module-enum)? – ekhumoro Jan 08 '15 at 03:35

2 Answers2

2

Dynamically setting variables is a truly terrible idea in more ways than I can count, but Python gives you enough rope to shoot yourself in the foot! At an interactive interpreter prompt it may be less horrible than anywhere else...

>>> x={'NON_EPISODIC_MOVIE': 11}
>>> vars().update(x)
>>> NON_EPISODIC_MOVIE
11

Works in both Python 2 and Python 3 interactive interpreters.

A better approach is to keep each bunch of such names-with-values within a class, which acts as its namespace. See http://code.activestate.com/recipes/52308-the-simple-but-handy-collector-of-a-bunch-of-named/ -- oldie, but goldie, if I say so myself:-). Just say, e.g

>>> movies = Bunch(**x)

and the global variables will be intact but movies.NON_EPISODIC_MOVIE will be 11 with zero risk of "namespace pollution" (the big problem with dynamically setting global variables)...

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Why would it be such a bad idea if the variable names are super-specific and would never be overwritten? For example, I have a list of 'content types' that I use through the application. So having access to `CONTENT_TYPE_SHORT_FILM` is much more readable than doing anything else. Or am I wrong here? – David542 Jan 08 '15 at 03:40
  • 1
    @David542 - Accidentally overwriting the names is just one of the problems. They also pollute the global namespace. Plus, it's hard to work with them as a whole. I mean, with the dictionary, you can get its length, add and remove items easily, print it, iterate over it, etc. Dynamic names however are just names. –  Jan 08 '15 at 03:49
  • 1
    A far superior approach is to keep each logical group of such constants in a class -- see e.g http://code.activestate.com/recipes/52308-the-simple-but-handy-collector-of-a-bunch-of-named/ ... oldie but goldie, if I say so myself:-). This will avoid just about every problem connected with making such constants into global variables! `import this` at a Python interpreter prompt -- each line is a gem of wisdom, but this is about the last, subtlest one...: "Namespaces are one honking great idea -- let's do more of those!". Keep bunches of name in a namespace: you'll live happier and saner!-) – Alex Martelli Jan 08 '15 at 03:49
2
>>> x={'NON_EPISODIC_MOVIE': 11}
>>> g = globals()
>>> for k, v in x.items():
...  g[k] = v
...
>>> NON_EPISODIC_MOVIE
11
>>>
SangYoung Lee
  • 146
  • 1
  • 2