2011-06-02 14 views
10

ConfigParser requiere que todas las secciones, claves y valores sean cadenas; No sorpresa. Tiene métodos para convertir los valores a tipos de datos con getfloat, getint, getboolean. Si usted no sabe el tipo de datos, se puede envolver el get() con un eval() para conseguir tener la cadena evaluada como:La conversión de los valores de ConfigParser a los tipos de datos de Python

>>> from ConfigParser import SafeConfigParser 
>>> cp = SafeConfigParser() 
>>> cp.add_section('one') 
>>> cp.set('one', 'key', '42') 
>>> print cp.get('one', 'key') 
'42' 
>>> print eval(cp.get('one', 'key')) 
42 
>>> cp.set('one', 'key', 'None') 
>>> print eval(cp.get('one', 'key')) 
None 
>>> 

¿Hay una mejor manera? Supongo que hay algunas preocupaciones de seguridad graves con la evaluación de texto de un archivo, que reconozco; Confío completamente en el archivo.

Pensé que usaría pickle para esto, pero realmente me gustaría mantener el archivo de configuración legible por humanos.

¿Cómo lo harías?

Respuesta

13

Si está utilizando Python 2.6 o superior puede utilizar ast.literal_eval:

ast.literal_eval (node_or_string)
evaluar de forma segura un nodo de expresión o una cadena que contiene una expresión de Python. La cadena o nodo proporcionado solo puede consistir en las siguientes estructuras literales de Python: cadenas, números, tuplas, listas, dictados, booleanos y Ninguno.

Esto se puede utilizar para evaluar con seguridad cadenas que contienen expresiones de Python de fuentes no confiables sin la necesidad de analizar los valores uno mismo.

Esto funciona así eval cuando la cadena es segura:

>>> literal_eval("{'key': 10}") 
{'key': 10} 

Pero va a fallar si nada, además de los tipos enumerados en la documentación aparece:

>>> literal_eval("import os; os.system('rm -rf somepath')") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib64/python2.6/ast.py", line 49, in literal_eval 
    node_or_string = parse(node_or_string, mode='eval') 
    File "/usr/lib64/python2.6/ast.py", line 37, in parse 
    return compile(expr, filename, mode, PyCF_ONLY_AST) 
    File "<unknown>", line 1 
    import os; os.system('rm -rf somepath') 
     ^
SyntaxError: invalid syntax 
+0

i utilizado su respuesta para crear esta: http: // codereview.stackexchange.com/questions/2775/python-subclassing-configparser – tMC

1

Si usted está en 2.7+ luego puede usar los métodos .getint.getfloat.getbool. Usted puede aprender más acerca de ellos en el docs

Por lo que su aplicación sería utilizar print cp.getint('one', 'key')

3

Para aquellos que pueden estar buscando otra respuesta más fácil, en lugar de tener que convertir los tipos de datos usted mismo, puede usar el módulo localconfig que hace la conversión por usted. La conversión se realiza adivinando el tipo de datos en función del valor (es decir, 123 es un int, 123.4 es un float, true es un bool, y así sucesivamente).

Aquí es un ejemplo a raíz de la OP de:

>>> from localconfig import config 
>>> config.read('[one]\nkey = 42\nkey2 = None') 
>>> config.one.key, type(config.one.key) 
(42, <type 'int'>) 
>>> config.one.key2, type(config.one.key2) 
(None, <type 'NoneType'>) 
>>> config.get('one', 'key'), config.get('one', 'key2') 
(42, None) 

Es un envoltorio en la parte superior de ConfigParser, por lo que es totalmente compatible.

echarle un vistazo en https://pypi.python.org/pypi/localconfig

+0

¡Gracias, sus paquetes fueron muy útiles para mí! – crazjo

Cuestiones relacionadas