web-dev-qa-db-fra.com

Fichier de propriétés en python (similaire à Java Properties)

Étant donné le format suivant (.properties ou .ini):

propertyName1=propertyValue1
propertyName2=propertyValue2
...
propertyNameN=propertyValueN

Pour Java, il existe la classe Properties qui offre des fonctionnalités permettant d'analyser/d'interagir avec le format ci-dessus.

Existe-t-il quelque chose de similaire dans la bibliothèque standard de python (2.x)?

Si non, quelles autres alternatives ai-je?

112
Andrei Ciobanu

Pour les fichiers .ini, le module ConfigParser fournit un format compatible avec les fichiers .ini.

Quoi qu'il en soit, il n'y a rien de disponible pour analyser des fichiers .properties complets, lorsque je dois le faire, j'utilise simplement jython (je parle de script).

55
pygabriel

J'ai pu faire en sorte que cela fonctionne avec ConfigParser, personne n'a montré d'exemples sur la façon de procéder. Voici donc un simple lecteur python d'un fichier de propriétés et un exemple du fichier de propriétés. Notez que l'extension est toujours .properties, mais j'ai dû ajouter un en-tête de section similaire à ce que vous voyez dans les fichiers .ini ... un peu d'une bâtardise, mais cela fonctionne.

Le fichier python: PythonPropertyReader.py

#!/usr/bin/python    
import ConfigParser
config = ConfigParser.RawConfigParser()
config.read('ConfigFile.properties')

print config.get('DatabaseSection', 'database.dbname');

Le fichier de propriétés: ConfigFile.properties

[DatabaseSection]
database.dbname=unitTest
database.user=root
database.password=

Pour plus de fonctionnalités, lisez: https://docs.python.org/2/library/configparser.html

55
James Oravec

Un fichier de propriétés Java est souvent un code python valide. Vous pouvez renommer votre fichier myconfig.properties en myconfig.py. Ensuite, importez votre fichier, comme ceci

import myconfig

et accéder directement aux propriétés

print myconfig.propertyName1
54
Travis Bear

Je sais que c'est une question très ancienne, mais j'en ai besoin tout à l'heure et j'ai décidé d'implémenter ma propre solution, une solution pure python, qui couvre la plupart des cas d'utilisation (pas tous):

def load_properties(filepath, sep='=', comment_char='#'):
    """
    Read the file passed as parameter as a properties file.
    """
    props = {}
    with open(filepath, "rt") as f:
        for line in f:
            l = line.strip()
            if l and not l.startswith(comment_char):
                key_value = l.split(sep)
                key = key_value[0].strip()
                value = sep.join(key_value[1:]).strip().strip('"') 
                props[key] = value 
    return props

Vous pouvez remplacer la sep par ':' pour analyser les fichiers au format:

key : value

Le code analyse correctement les lignes comme:

url = "http://my-Host.com"
name = Paul = Pablo
# This comment line will be ignored

Vous obtiendrez un dict avec:

{"url": "http://my-Host.com", "name": "Paul = Pablo" }
44
Roberto

Si vous avez une option de formats de fichiers, je vous suggère d'utiliser .ini et ConfigParser de Python, comme indiqué. Si vous avez besoin de compatibilité avec les fichiers .properties Java, j’ai écrit une bibliothèque appelée jprops . Nous utilisions pyjavaproperties, mais après avoir rencontré diverses limitations, j'ai fini par mettre en œuvre la mienne. Il prend totalement en charge le format .properties, y compris le support unicode et un meilleur support pour les séquences d'échappement. Jprops peut également analyser n'importe quel objet de type fichier alors que pyjavaproperties ne fonctionne qu'avec des fichiers réels sur disque.

15
Matt Good

Ce ne sont pas exactement des propriétés, mais Python a un Nice library pour analyser les fichiers de configuration. Voir également cette recette: Un remplacement python pour Java.util.Properties .

6
Manoj Govindan

si vous n'avez pas de propriétés multilignes et un besoin très simple, quelques lignes de code peuvent le résoudre:

Fichier t.properties:

a=b
c=d
e=f

Code python:

with open("t.properties") as f:
    l = [line.split("=") for line in f.readlines()]
    d = {key.strip(): value.strip() for key, value in l}
4
mvallebr

Voici un lien vers mon projet: https://sourceforge.net/projects/pyproperties/ . C'est une bibliothèque avec des méthodes d'utilisation des fichiers * .properties pour Python 3.x. 

Mais ce n'est pas basé sur Java.util.Properties

4
marekjm

Si vous devez lire toutes les valeurs d’une section dans le fichier de propriétés d’une manière simple:

La structure de votre fichier config.properties:

[SECTION_NAME]  
key1 = value1  
key2 = value2  

Vous code:

   import configparser

   config = configparser.RawConfigParser()
   config.read('path_to_config.properties file')

   details_dict = dict(config.items('SECTION_NAME'))

Cela vous donnera un dictionnaire où les clés sont les mêmes que dans le fichier de configuration et leurs valeurs correspondantes. 

details_dict est:

{'key1':'value1', 'key2':'value2'}

Maintenant, pour obtenir la valeur de key1: details_dict['key1']

Tout mettre dans une méthode qui lit cette section du fichier de configuration une seule fois (la première fois que la méthode est appelée lors de l'exécution d'un programme).

def get_config_dict():
    if not hasattr(get_config_dict, 'config_dict'):
        get_config_dict.config_dict = dict(config.items('SECTION_NAME'))
    return get_config_dict.config_dict

Appelez maintenant la fonction ci-dessus et obtenez la valeur de la clé requise:

config_details = get_config_dict()
key_1_value = config_details['key1'] 

-------------------------------------------------- -----------

Prolongement de l'approche mentionnée ci-dessus, lecture section par section automatiquement, puis accès par nom de section suivi d'un nom de clé.

def get_config_section():
    if not hasattr(get_config_section, 'section_dict'):
        get_config_section.section_dict = dict()

        for section in config.sections():
            get_config_section.section_dict[section] = 
                             dict(config.items(section))

    return get_config_section.section_dict

Accéder:  

config_dict = get_config_section()

port = config_dict['DB']['port'] 

(ici 'DB' est un nom de section dans le fichier de configuration et 'port' est une clé dans la section 'DB'.)

2
MANU

Ceci est un remplacement individuel de Java.util.Propeties

De la doc:

  def __parse(self, lines):
        """ Parse a list of lines and create
        an internal property dictionary """

        # Every line in the file must consist of either a comment
        # or a key-value pair. A key-value pair is a line consisting
        # of a key which is a combination of non-white space characters
        # The separator character between key-value pairs is a '=',
        # ':' or a whitespace character not including the newline.
        # If the '=' or ':' characters are found, in the line, even
        # keys containing whitespace chars are allowed.

        # A line with only a key according to the rules above is also
        # fine. In such case, the value is considered as the empty string.
        # In order to include characters '=' or ':' in a key or value,
        # they have to be properly escaped using the backslash character.

        # Some examples of valid key-value pairs:
        #
        # key     value
        # key=value
        # key:value
        # key     value1,value2,value3
        # key     value1,value2,value3 \
        #         value4, value5
        # key
        # This key= this value
        # key = value1 value2 value3

        # Any line that starts with a '#' is considerered a comment
        # and skipped. Also any trailing or preceding whitespaces
        # are removed from the key/value.

        # This is a line parser. It parses the
        # contents like by line.
2
tmow

J'ai créé un module python presque similaire à la classe Properties de Java (en réalité, il ressemble au PropertyPlaceholderConfigurer de Spring qui vous permet d'utiliser $ {variable-reference} pour faire référence à une propriété déjà définie)

EDIT: Vous pouvez installer ce paquet en lançant la commande (actuellement testé pour python 3).
pip install property

Le projet est hébergé sur GitHub

Exemple: (Une documentation détaillée peut être trouvée ici )

Supposons que les propriétés suivantes soient définies dans le fichier my_file.properties.

foo = I am awesome
bar = ${chocolate}-bar
chocolate = fudge

Code pour charger les propriétés ci-dessus

from properties.p import Property

prop = Property()
# Simply load it into a dictionary
dic_prop = prop.load_property_files('my_file.properties')
2
Anand Joshi

Vous pouvez utiliser un objet de type fichier dans ConfigParser.RawConfigParser.readfp défini ici -> https://docs.python.org/2/library/configparser.html#ConfigParser.RawConfigParser.readfp

Définissez une classe qui remplace readline et qui ajoute un nom de section avant le contenu réel de votre fichier de propriétés.

Je l'ai intégré dans la classe qui renvoie dict de toutes les propriétés définies.

import ConfigParser

class PropertiesReader(object):

    def __init__(self, properties_file_name):
        self.name = properties_file_name
        self.main_section = 'main'

        # Add dummy section on top
        self.lines = [ '[%s]\n' % self.main_section ]

        with open(properties_file_name) as f:
            self.lines.extend(f.readlines())

        # This makes sure that iterator in readfp stops
        self.lines.append('')

    def readline(self):
        return self.lines.pop(0)

    def read_properties(self):
        config = ConfigParser.RawConfigParser()

        # Without next line the property names will be lowercased
        config.optionxform = str

        config.readfp(self)
        return dict(config.items(self.main_section))

if __== '__main__':
    print PropertiesReader('/path/to/file.properties').read_properties()
2

C’est ce que je fais dans mon projet: je viens de créer un autre fichier .py appelé properties.py, qui inclut toutes les variables/propriétés courantes que j’ai utilisées dans le projet, et qui doit faire référence à ces variables.

from properties import *(or anything you need)

Cette méthode a été utilisée pour garder svn peace lorsque je changeais fréquemment d’emplacement de dev et que certaines variables communes étaient relativement relatives à l’environnement local. Cela fonctionne bien pour moi mais je ne suis pas sûr que cette méthode serait suggérée pour un environnement de développement formel, etc.

2
festony

En dessous de 2 lignes de code, vous apprendrez à utiliser Python List Comprehension pour charger le fichier de propriétés 'Style Java'. 

split_properties=[line.split("=") for line in open('/<path_to_property_file>)]
properties={key: value for key,value in split_properties }

Veuillez consulter l'article ci-dessous pour plus de détails https://ilearnonlinesite.wordpress.com/2017/07/24/reading-property-file-in-python-using-comprehension-and-generators/

1
Anoop Isaac
import json
f=open('test.json')
x=json.load(f)
f.close()
print(x)

Contenu de test.json: {"Host": "127.0.0.1", "user": "jms"}

1
jms

créez un dictionnaire dans votre module python, stockez-le dans le répertoire et accédez-y, par exemple:

dict = {
       'portalPath' : 'www.xyx.com',
       'elementID': 'submit'}

Maintenant, pour y accéder, vous pouvez simplement faire:

submitButton = driver.find_element_by_id(dict['elementID'])
1
Vineet Singh

Lightbend a publié la bibliothèque Typesafe Config , qui analyse les fichiers de propriétés et certaines extensions basées sur JSON. La bibliothèque Lightbend ne concerne que la machine virtuelle Java, mais elle semble être largement adoptée et il existe maintenant des ports dans de nombreuses langues, y compris Python: https://github.com/chimpler/pyhocon

0
DGrady

cela fonctionne pour moi.

from pyjavaproperties import Properties
p = Properties()
p.load(open('test.properties'))
p.list()
print p
print p.items()
print p['name3']
0
Andy Quiroz

Vous pouvez utiliser la fonction suivante, qui est le code modifié de @mvallebr. Il respecte les commentaires du fichier de propriétés, ignore les nouvelles lignes vides et permet de récupérer une valeur de clé unique.

def getProperties(propertiesFile ="/home/memin/.config/customMemin/conf.properties", key=''):
    """
    Reads a .properties file and returns the key value pairs as dictionary.
    if key value is specified, then it will return its value alone.
    """
    with open(propertiesFile) as f:
        l = [line.strip().split("=") for line in f.readlines() if not line.startswith('#') and line.strip()]
        d = {key.strip(): value.strip() for key, value in l}

        if key:
            return d[key]
        else:
            return d
0
Memin

j'ai utilisé cela, cette bibliothèque est très utile

from pyjavaproperties import Properties
p = Properties()
p.load(open('test.properties'))
p.list()
print(p)
print(p.items())
print(p['name3'])
p['name3'] = 'changed = value'
0
Andy Quiroz

Je l'ai fait en utilisant ConfigParser comme suit. Le code suppose qu’il existe un fichier appelé config.prop dans le même répertoire que BaseTest:

config.prop

[CredentialSection]
app.name=MyAppName

BaseTest.py:

import unittest
import ConfigParser

class BaseTest(unittest.TestCase):
    def setUp(self):
        __SECTION = 'CredentialSection'
        config = ConfigParser.ConfigParser()
        config.readfp(open('config.prop'))
        self.__app_name = config.get(__SECTION, 'app.name')

    def test1(self):
        print self.__app_name % This should print: MyAppName
0
narko

C’est ce que j’avais écrit pour analyser le fichier et le définir en tant que variables env qui ignorent les commentaires et les lignes de valeur non essentielles ajoutées aux commutateurs pour spécifier. hg: d

  • -h ou --help récapitulatif d'utilisation
  • -c Spécifie le caractère qui identifie un commentaire
  • -s Séparateur entre clé et valeur dans le fichier prop
  • et spécifiez le fichier de propriétés à analyser, par exemple: pythonEnvParamSet.py -c # -s = env.properties

    import pipes
    import sys , getopt
    import os.path
    
    class Parsing :
    
            def __init__(self , seprator , commentChar , propFile):
            self.seprator = seprator
            self.commentChar = commentChar
            self.propFile  = propFile
    
        def  parseProp(self):
            prop = open(self.propFile,'rU')
            for line in prop :
                if line.startswith(self.commentChar)==False and  line.find(self.seprator) != -1  :
                    keyValue = line.split(self.seprator)
                    key =  keyValue[0].strip() 
                    value = keyValue[1].strip() 
                            print("export  %s=%s" % (str (key),pipes.quote(str(value))))
    
    
    
    
    class EnvParamSet:
    
        def main (argv):
    
            seprator = '='
            comment =  '#'
    
            if len(argv)  is 0:
                print "Please Specify properties file to be parsed "
                sys.exit()
            propFile=argv[-1] 
    
    
            try :
                opts, args = getopt.getopt(argv, "hs:c:f:", ["help", "seprator=","comment=", "file="])
            except getopt.GetoptError,e:
                print str(e)
                print " possible  arguments  -s <key value sperator > -c < comment char >    <file> \n  Try -h or --help "
                sys.exit(2)
    
    
            if os.path.isfile(args[0])==False:
                print "File doesnt exist "
                sys.exit()
    
    
            for opt , arg  in opts :
                if opt in ("-h" , "--help"):
                    print " hg:d  \n -h or --help print usage summary \n -c Specify char that idetifes comment  \n -s Sperator between key and value in prop file \n  specify file  "
                    sys.exit()
                Elif opt in ("-s" , "--seprator"):
                    seprator = arg 
                Elif opt in ("-c"  , "--comment"):
                    comment  = arg
    
            p = Parsing( seprator, comment , propFile)
            p.parseProp()
    
        if __== "__main__":
                main(sys.argv[1:])
    
0
patel

J'ai suivi l'approche de configparser et cela a très bien fonctionné pour moi. Création d’un fichier PropertyReader et utilisation de l’analyseur de configuration pour une propriété prête correspondant à chaque section.

** Utilisé Python 2.7

Contenu du fichier PropertyReader.py:

#!/usr/bin/python
import ConfigParser

class PropertyReader:

def readProperty(self, strSection, strKey):
    config = ConfigParser.RawConfigParser()
    config.read('ConfigFile.properties')
    strValue = config.get(strSection,strKey);
    print "Value captured for "+strKey+" :"+strValue
    return strValue

Contenu du fichier de schéma lu:

from PropertyReader import *

class ReadSchema:

print PropertyReader().readProperty('source1_section','source_name1')
print PropertyReader().readProperty('source2_section','sn2_sc1_tb')

Contenu du fichier .properties:

[source1_section]
source_name1:module1
sn1_schema:schema1,schema2,schema3
sn1_sc1_tb:employee,department,location
sn1_sc2_tb:student,college,country

[source2_section]
source_name1:module2
sn2_schema:schema4,schema5,schema6
sn2_sc1_tb:employee,department,location
sn2_sc2_tb:student,college,country
0
Vaibhav Shukla