开发者

Python: should I use eval, exec or ..?

I am trying to make the following statement more flexible:

for posting in page.findAll(attrs = {"id": re.compile(r'''post\d+''')})开发者_如何学JAVA:

The following part is retrieved dynamically from a CSV file and stored in a string (for example the string called test). The CSV is stored in a secure location, accessible for admins only.

attrs = {"id": re.compile(r'''post\d+''')}

Can I integrate the variable as following by using an eval(test) or exec(test) in stead of just test?

for posting in page.findAll(test)):


If you want to run code from user input (file contents are input), you'll need eval or exec, by these names or some other (specifically, you need exec for statements - assignment is a statement).

But you don't want to (and shouldn't) do that, because that's evil, insecure, totally unnecessary, etc. Drop the assignment (just store the dict) and the re.compile call, then you can use ast.literal_eval on it and you're quite safe (you should still catch syntax errors and everything else that may go wrong to display a sensible error message, but malicious code should be close to impossible and it's not nearly as dirty). You can apply the re.compile after loading if you thing it's needed.


Unless you have absolutely no control over the CSV source, avoid, at all cost these kinds of loading.

  • save the regex as seriliazed data using the pickle module (or better, just save the string)
  • Save your data as JSON using the json module
  • write it to a file using the csv module

Then do the opposite to get the data from the file.

If you can't control the CSV generation, try extracting the data manually using split or the re module.

eval and exec are 'last chance solution'. Avoid using them unless you have no other ways.


The most secure is ast.literal_eval():

>>> args = ast.literal_eval('{"a":1}')
>>> args
{'a': 1}

You can use it as:

some_function_or_method(**args)


Neither - this is Python - you can write a eries of named parameters and the desired values to call a function as dictionary. In this case, a dictionary which value fot the key "attrs" is also a dictionary. Just prepend to "**" to the dictionary name when calling the function:

test= {"attrs": {\"id\": re.compile(r'''post\d+''')} }

for posting in page.findAll(**test}):
   (...)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜