使用Python compile函数读取配置文件报错的问题排查与解决
Hey there, let's break down why your code is throwing an error and how to fix it.
问题背景
You're attempting to convert a config file into a Python dictionary using compile() and exec(), but hitting a syntax error during compilation. Here's your setup:
你的Python代码
def config2dict(fname): d = {} codeobj = compile(open(fname).read(), 'myconfig', 'exec') exec(codeobj, d) return d dd = config2dict("myconfig.cfg") print(dd)
配置文件myconfig.cfg内容
DB_HOST = 172.123.125.34 DB_USER = app_user DB_PASS = lly4paw
报错信息
Traceback (most recent call last):
File "mytest.py", line 19, in
dd = config2dict("myconfig.cfg")
File "mytest.py", line 14, in config2dict
codeobj = compile(open(fname).read(), 'myconfig', 'exec')
File "myconfig", line 1
DB_HOST = 172.123.125.34
问题原因
The core issue is that your config file isn't valid Python syntax:
172.123.125.34looks like a malformed floating-point number to Python (you can't have three decimal dots in a number), so the compiler rejects it.- Values like
app_userandlly4paware unquoted, so Python tries to interpret them as variable names instead of literal strings.
When compile() tries to parse this content as executable Python code, it hits these syntax violations and throws an error.
解决办法
方案1:修改配置文件为合法Python代码
Wrap all your config values in single or double quotes to turn them into valid string literals:
DB_HOST = '172.123.125.34' DB_USER = 'app_user' DB_PASS = 'lly4paw'
Now compile() will recognize the content as valid Python, and your original code will work as expected.
方案2:使用更安全的专用配置解析器(推荐)
Using exec() on external files carries a security risk—if someone modifies the config file to include malicious code, it will execute directly. A better practice is to use Python's built-in configparser module, which is designed specifically for handling config files.
Here's how to rewrite your function with configparser:
import configparser def config2dict(fname): config = configparser.ConfigParser() # Handle config files without section headers (like your current file) config.read_dict({'DEFAULT': {}}) config.read(fname) return dict(config['DEFAULT']) dd = config2dict("myconfig.cfg") print(dd)
Your original config file can stay exactly as it is—no changes needed. This method is safer, more maintainable, and avoids syntax-related headaches entirely.
内容的提问来源于stack exchange,提问作者rnso

