2009-08-21 9 views
8

Lors de l'utilisation du module ConfigParser, je voudrais utiliser des valeurs contenant plusieurs mots dans un fichier cfg. Dans ce cas, me semble trivial pour pour entourer la chaîne avec des citations comme (example.cfg):Python ConfigParser - valeurs entre guillemets

[GENERAL] 
onekey = "value in some words" 

Mon problème est que dans ce python cas ajoute les citations à la chaîne et lors de l'utilisation de la valeur comme ceci:

config = ConfigParser() 
config.read(["example.cfg"]) 
print config.get('GENERAL', 'onekey') 

Je suis sûr qu'il y a une fonctionnalité intégrée pour réussir à imprimer seulement 'value in some words' au lieu de '"value in some words"'. Comment est-ce possible? Merci.

Répondre

9

Je n'ai rien vu dans the configparser manual, mais vous pouvez simplement utiliser la méthode de chaînes .strip pour vous débarrasser des doubles guillemets avant et arrière.

>>> s = '"hello world"' 
>>> s 
'"hello world"' 
>>> s.strip('"') 
'hello world' 
>>> s2 = "foo" 
>>> s2.strip('"') 
'foo' 

Comme vous pouvez le voir, .strip ne modifie pas la chaîne si elle ne démarre pas et se terminent par la chaîne spécifiée.

+0

Notez la dernière phrase devrait être mis à jour. 'strip()' DOES modifie la chaîne si elle commence OU finit avec la chaîne spécifiée. par exemple. '' "bar'.strip (" '")' renvoie '' bar'' et non 'bar'. – Jonny

2

Désolé, la solution était triviale aussi - je peux simplement laisser les guillemets, il semble que python prend simplement le côté droit du signe égal.

0

Davey,

Comme vous le dites, vous pouvez simplement laisser les citations de votre chaîne.

Pour un projet sur lequel je travaille, je voulais pouvoir représenter presque tout littéral de chaîne Python comme une valeur pour certaines de mes options de configuration et plus au point que je voulais être capable de gérer certaines d'entre elles comme premières littéraux de chaîne. (Je veux que cette config soit capable de gérer des choses comme \ n, \ x1b, et ainsi de suite).

Dans ce cas, j'utilisé quelque chose comme:

def EvalStr(s, raw=False): 
    r'''Attempt to evaluate a value as a Python string literal or 
     return s unchanged. 

     Attempts are made to wrap the value in one, then the 
     form of triple quote. If the target contains both forms 
     of triple quote, we'll just punt and return the original 
     argument unmodified. 

     Examples: (But note that this docstring is raw!) 
     >>> EvalStr(r'this\t is a test\n and only a \x5c test') 
     'this\t is a test\n and only a \\ test' 

     >>> EvalStr(r'this\t is a test\n and only a \x5c test', 'raw') 
     'this\\t is a test\\n and only a \\x5c test' 
    ''' 

    results = s ## Default returns s unchanged 
    if raw: 
     tmplate1 = 'r"""%s"""' 
     tmplate2 = "r'''%s'''" 
    else: 
     tmplate1 = '"""%s"""' 
     tmplate2 = "'''%s'''" 

    try: 
     results = eval(tmplate1 % s) 
    except SyntaxError: 
    try: 
     results = eval(tmplate2 %s) 
    except SyntaxError: 
     pass 
    return results 

... qui, je pense gérer tout ce qui ne contient pas les deux chaînes entre guillemets triples simples et triples-doubles.

(Ce cas de coin est bien au-delà de mes exigences).

Il y a une bizarrerie de ce code ici sur SO; le surligneur de syntaxe semble être confondu par le fait que ma docstring est une chaîne brute. C'était nécessaire pour rendre doctest heureux pour cette fonction particulière).

5
import ConfigParser 

class MyConfigParser(ConfigParser.RawConfigParser): 
    def get(self, section, option): 
     val = ConfigParser.RawConfigParser.get(self, section, option) 
     return val.strip('"') 

if __name__ == "__main__": 
    #config = ConfigParser.RawConfigParser() 
    config = MyConfigParser() 

    config.read(["example.cfg"]) 
    print config.get('GENERAL', 'onekey') 
2

La question est déjà assez ancienne, mais dans 2.6 au moins, vous n'avez pas besoin d'utiliser des guillemets car les espaces sont conservés.

from ConfigParser import RawConfigParser 
from StringIO import StringIO 

s = RawConfigParser() 
s.readfp(StringIO('[t]\na= 1 2 3')) 
s.get('t','a') 
> '1 2 3' 

Cela ne s'applique pas aux espaces de début et de fin! Si vous souhaitez les conserver, vous devrez les placer entre guillemets et procéder comme indiqué. Évitez d'utiliser le mot clé eval car vous aurez un trou de sécurité énorme.

-2

Dans cette situation, la solution la plus simple est "eval()".

Cependant, vous pouvez vous inquiéter de la sécurité.Mais vous pouvez toujours le faire par:

def literal_eval(node_or_string): 
    """ 
    Safely evaluate an expression node or a string containing a Python 
    expression. The string or node provided may only consist of the following 
    Python literal structures: strings, numbers, tuples, lists, dicts,booleans, 
    and None. 
    """ 

comme échantillon:

import ast 
config = ConfigParser() 
config.read(["example.cfg"]) 
print ast.literal_eval(config.get('GENERAL', 'onekey')) 
# value in some words 
Questions connexes