0

I've been using Python 2 for several months now, and commonly use eval() to dynamically set variables. For example:

num_ls = [1,2,3]
let_ls = ['a', 'b', 'c']

what2plot = 'num'
list2plot = eval(what2plot + '_ls')

Today, all of my code written this day suddenly hits an error when I use eval().

The error is:

Traceback (most recent call last):

File "", line 1, in list2plot = eval(what2plot + '_ls')

File "/anaconda/lib/python2.7/site-packages/pandas/computation/eval.py", line 266, in eval ret = eng_inst.evaluate()

File "/anaconda/lib/python2.7/site-packages/pandas/computation/engines.py", line 76, in evaluate res = self._evaluate()

File "/anaconda/lib/python2.7/site-packages/pandas/computation/engines.py", line 123, in _evaluate return ne.evaluate(s, local_dict=scope, truediv=truediv)

File "/anaconda/lib/python2.7/site-packages/numexpr/necompiler.py", line 789, in evaluate zip(names, arguments)]

File "/anaconda/lib/python2.7/site-packages/numexpr/necompiler.py", line 686, in getType raise ValueError("unknown type %s" % a.dtype.name)

ValueError: unknown type unicode1792

pavlov
  • 111
  • 2
  • 16
  • 4
    You shouldn't be using `eval()` in the first place. Also, you have a typo. You wrote `what2pot = "num"` instead of `what2plot = "num"` – stelioslogothetis Sep 01 '17 at 22:52
  • 6
    What do you mean, you "commonly use eval()"?! You should (almost) never use eval. – melpomene Sep 01 '17 at 23:01
  • 3
    "commonly use eval() to dynamically set variables." **do not do this**. It is slow, inefficient, and asking for bugs. – juanpa.arrivillaga Sep 01 '17 at 23:10
  • 1
    My coworker has made the observation that you can't ask a question on StackOverflow without getting into a morality argument, and this is the second time I've seen it in just the last hour. Regardless of whether this is a good idea or not, the problem seems real and could use an answer. Why would `eval` fail in this fashion? – Mark Ransom Sep 01 '17 at 23:21
  • Given the traceback, there is a *lot* of context missing from the code you posted, so it's going to be hard to explain what, exactly, is happening. The advice stands, though: *stop using `eval` like this*. – chepner Sep 01 '17 at 23:30
  • Would love to know *why* I shouldn't be using eval() like this. What are good alternatives? Regardless, the code I described above using eval() spontaneously started spitting out this error... – pavlov Sep 02 '17 at 02:45
  • 1
    @pavlov See [this question](https://stackoverflow.com/questions/1832940/why-is-using-eval-a-bad-practice) for some discussion on `eval()`. For example, in the code you posted, why not just use a dictionary that maps possible values of `what2plot` to their matching lists? – Josh Karpel Sep 02 '17 at 03:31
  • Thanks! Looks like using a dict will be faster than eval, and better for debugging purposes? Makes sense, although when I use eval() it's always at the start of a small block of code I using for plotting data or something, so speed differences will be trivial and debugging isn't really problematic in such cases. – pavlov Sep 02 '17 at 03:56

1 Answers1

3

Your code isn't working as you expect because you're not running the normal builtin eval function, but instead a function from pandas. You probably have a from some_module import * statement that's bringing the pandas eval function into your namespace where it hides the builtin function.

There are a variety of ways you can solve this.

The simplest might be to just not do that import. Another option would be to do del eval, which will remove the imported function from your namespace, allowing the builtin function to be visible again. You could also import it again from the builtins module (or __builtin__ for Python 2).

But a better approach is probably to not use eval at all. It's unsafe, slow and hard to debug if you encounter any issues. A much better alternative would be to use a dictionary to map between your strings and lists:

num_ls = [1,2,3]
let_ls = ['a', 'b', 'c']
selector_dict = {'num': num_ls, 'let': let_ls}

what2plot = 'num'
list2plot = selector_dict[what2plot]
Blckknght
  • 100,903
  • 11
  • 120
  • 169