What is the benefit of using the ConfigParser instead of a regular python.py file when writing configuration files?
I have been using the ConfigParser module to write configuration files for some time. However, a thought recently struck me; why not just use pure Python instead? Take this example configuration file:
[parameters]
# Host
host = stackoverflow.com
port = 22
To read these values into my code, I do
import ConfigParser
config = ConfigParser.SafeConfigParser()
config.read('host.cfg')
host = config.get('parameters', 'host')
port = config.get('parameters', 'port')
On the other hand, if I had a config file like this:
# Host
host = 'stackoverflow.com'
port = 22
In my main code, I could do this:
from host_cfg import *
So what do I gain fr开发者_Python百科om using the ConfigParser module? What are the pros and cons of each approach?
So what do I gain from using the ConfigParser module?
Compatibility with Windows .ini files. Makes some people happy.
What are the pros and cons of each approach?
ConfigParser has limited syntax and some relatively simple things get very contrived. Look at logging
for examples.
Python syntax is simpler and much easier to work with. There's no security hole, since no one will waste time hacking a config file when they can simply hack your source code. Indeed, they can hack most of the built-in Python library. For that matter, they could cook the Python interpreter itself.
No one wastes time hacking config files when there are much, much easier exploits elsewhere in your application source code.
ConfigParser parses simple, flat configuration data. Importing a python module runs code. For configuration files, you want data, not code. Case closed.
Okay, more detailed: Code can do all kinds of things, including breaking more easily - especially when edited by non-programmers (try explaining .ini
modders that they e.g. have to use matched quotes and escape things...) - or cause namespace conflicts with other parts of your application (especially if you import *
). Also see the rule of Least Power.
A potential "con" of the Python file approach is that your user can put arbitrary code in the file that will be executed in your application's context. As S. Lott points out in the comments to this answer (when I was somewhat more forceful in my warning), this is usually not an issue because the user (or a hacker) will usually have access to your entire source code anyway and can make any desired changes.
However, I can certainly imagine situations in which the approach could result in a new security hole, such as when the main script files are writable only by the system administrator and the per-user config file is the only file editable by the end user. Unless you are certain that your code will never run in such an environment, I would not recommend the Python module approach. There are good reasons that "don't execute code given to you by users" is widely considered a best practice.
Executing the config file also makes handling errors problematic. If the user introduces a syntax error, you will want to trap it, and you can do so easily by throwing a try
around your import
, but nothing after the error will be executed. In a config file, usually parsing will continue with the next line, so the user will miss at most one setting instead of (say) half of them. There are ways to make a Python module work more like a config file (you could read the file as text and exec()
each line, for example) but if you have to do any work at all, it becomes easier to use ConfigParser
.
If, despite all this, you still want to use Python syntax in your config file, you could use the ast
module (see function literal_eval()
).
精彩评论