É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?
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).
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
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
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" }
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.
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 .
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}
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
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'.)
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.
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')
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()
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.
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/
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"}
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'])
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
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']
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
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'
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
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
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:])
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