Pythonのプロパティファイル(Javaプロパティと同様)


137

次の形式(.propertiesまたは.ini)があるとします。

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

以下のためのJavaがあり、プロパティクラスは、その上記の形式での解析/対話するために提供する機能が。

python標準ライブラリ(2.x)に似たものはありますか?

そうでない場合、他にどのような選択肢がありますか?


5
これはJavaの質問ではありません。なぜJavaタグの削除をロールバックしたのですか?
BalusC 2010

回答:


69

.iniファイルの場合、.iniファイルと互換性のある形式を提供するConfigParserモジュールがあります。

とにかく、完全な.propertiesファイルを解析するために利用できるものは何もありません。そうする必要があるときは、単にjythonを使用します(スクリプトについて話している)。


10
Jythonを使用したくない場合は、pyjavapropertiesがオプションのようです:bitbucket.org/jnoller/pyjavaproperties
Hans-Christoph Steiner

2
Javaプロパティファイルは.iniファイルと同等ではありません。pyjavapropertiesが正解です
igni 14

2
Alex Matelliは、ConfigParserを使用して.propertiesファイルを簡単に解析する方法を提案しました

bitbucket.org/jnoller/pyjavapropertiesは2010年以来維持されていません。それはpython 3と互換性がありません。@ piによってリンクされたソリューションを使用します。
codyzu

ここにはどこにも言及されていないので、これは同じではないことをもう一度付け加えましょう。私はJavaやPy3について話すことができません、そしておそらくそれは単純なキー/値のために働きます。ただし、文字列補間の構文は異なります。このソリューションは、Pythonのフォーマットを提供します。%(string)s while(例えばAnt)私は$ {string}を使用します。pymotw.com/2/ConfigParser
mpe

74

私はこれをで動作させることができました。これをConfigParser行う方法の例は誰も示していなかったため、プロパティファイルの簡単なpythonリーダーとプロパティファイルの例を次に示します。拡張子はまだ.propertiesですが、.iniファイルに表示されるものと同様のセクションヘッダーを追加する必要があることに注意してください。

Pythonファイル: PythonPropertyReader.py

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

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

プロパティファイル: ConfigFile.properties

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

その他の機能については、https//docs.python.org/2/library/configparser.htmlをご覧ください。


5
ConfigParserモジュールは、Python 3でのConfigParserに改名されました
Gursewakシン

これは.propertiesファイルではなく.iniファイル用であり、セクションが含まれていないため、セクションヘッダーが見つからない場合、configParserは失敗します。さらに、iniファイルにはセクションが含まれていない可能性があるため、このconfigParserはまったく信頼できないようです
BiAiB

65

多くの場合、Javaプロパティファイルも有効なPythonコードです。myconfig.propertiesファイルの名前をmyconfig.pyに変更できます。次に、このようにファイルをインポートします

import myconfig

プロパティに直接アクセスします

print myconfig.propertyName1

11
アイデアは好きですが、ドットを含むプロパティでは機能しません。つまりprop.name="val"、この場合は機能しません。
maxjakob 2012

36
A java properties file is valid python code:違います。一部の Javaプロパティファイルは有効なPythonコードを渡しますが、すべてが渡されるわけではありません。@mmjjが言ったように、ドットは問題です。引用符で囲まれていないリテラル文字列も同様です。-1。
Manoj Govindan、2012年

24
かなり悪い考え...それは壊れているので。Java propファイルでは、「=」ではなく「:」を使用できます。彼らは行継続の後に空白を食べます。文字列を引用しません。「有効なPython」ではありません。
Dan H

2
Javaプロパティファイルは、通常、有効なpythonコードでは渡されません。1つの代替策は、Pythonファイルでプロパティを設定し、有効なPythonを使用することです(例:MEDIA_ROOT = '/ foo')...
danbgray

3
これはハックを避けるのが最善です。プロパティが変更されてファイルが有効なpythonでなくなったときは、悪い日になるでしょう。
r_2

59

これは非常に古い質問であることはわかっていますが、今すぐ必要なので、ほとんどすべてのユースケース(すべてではない)をカバーする、独自のソリューションである純粋なPythonソリューションを実装することにしました。

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

次のsep形式でファイルを解析するには、「:」に変更します。

key : value

コードは次のような行を正しく解析します。

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

あなたは口述を得るでしょう:

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

1
一流のソリューションであり、まさに私が探していたものです!
ラッセル

これはのようなエントリと同じ行のコメントをサポートしないことに注意してくださいfoo = "bar" # bat
ThomasW 2017

1
@ThomasW事実上の標準としてJavaを使用している場合、Properties#loadはそれfooをvalue を持つプロパティとして扱います"bar" # bat
bon

1
古い質問への回答を投稿する意味は何ですか?ポイントは、これを自分で実装するのではなく、紺碧のパイプラインの1つにコピーアンドペーストするだけで時間を節約できたことです。そう感謝:)
老僧

1
答えが大好きです!インラインコメントを処理するために私が行った唯一の変更は、に変更l = line.strip()して、の値が次の行ではなくl = line.split(comment_char)[0].strip()かどうかlを確認することだけif l:でした。
ベンダリング

17

ファイル形式のオプションがある場合は、前述のように.iniおよびPythonのConfigParserを使用することをお勧めします。Java .propertiesファイルとの互換性が必要な場合は、jpropsというライブラリを作成しました。私たちはpyjavapropertiesを使用していましたが、さまざまな制限に遭遇した後、自分で実装することになりました。Unicodeのサポートやエスケープシーケンスのサポートの改善など、.properties形式を完全にサポートしています。Jpropsはファイルのようなオブジェクトも解析できますが、pyjavapropertiesはディスク上の実際のファイルでのみ機能します。


1
私はこれを試してみました。魅力のように機能します。MattGoodの+1!
Dan H

1
pip installとコード例を追加すると、open(path)をfpとして、pip install jpropsがより適切になります。properties= jprops.load_properties(fp)print(properties)
Rubber Duck

10

複数行のプロパティがなく、非常に単純な必要性がない場合は、数行のコードで解決できます。

ファイルt.properties

a=b
c=d
e=f

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}

6

これは厳密にはプロパティではありませんが、Pythonには構成ファイルを解析するための優れたライブラリがあります。次のレシピもご覧ください:java.util.Propertiesのpythonの置き換え


1
2番目のリンクについて...これは、もはや積極的に開発されていません。Jesse nollerがこのレシピからプロジェクトを作成しましたが、ここでは利用できない修正がいくつかあります。著者は、このレシピを使用しているすべての人にそのプロジェクトを推奨しています。pypi.python.org/pypi/pyjavaproperties
Big Al

4

これが私のプロジェクトへのリンクです:https : //sourceforge.net/projects/pyproperties/。これは、Python 3.xの* .propertiesファイルを操作するためのメソッドを備えたライブラリです。

しかし、それはjava.util.Propertiesに基づいていません


3

これは、java.util.Propetiesの1対1の置き換えです。

ドキュメントから:

  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.

3

ConfigParser.RawConfigParser.readfpここで定義されているファイルのようなオブジェクトを使用できます-> https://docs.python.org/2/library/configparser.html#ConfigParser.RawConfigParser.readfp

readlineプロパティファイルの実際の内容の前にセクション名を追加するオーバーライドするクラスを定義します。

dict定義したすべてのプロパティのを返すクラスにパッケージ化しました。

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 __name__ == '__main__':
    print PropertiesReader('/path/to/file.properties').read_properties()

3

私はこれを使用しました、このライブラリは非常に便利です

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'

2

これは私がプロジェクトでやっていることです:プロジェクトで使用したすべての一般的な変数/プロパティを含むproperties.pyと呼ばれる別の.pyファイルを作成し、すべてのファイルでこれらの変数を参照する必要があります。

from properties import *(or anything you need)

私が開発場所を頻繁に変更していて、いくつかの一般的な変数がローカル環境にかなり関連していたときに、この方法を使用してsvnの平和を維持しました。私には問題なく動作しますが、この方法が正式な開発環境などに推奨されるかどうかはわかりません。


2
import json
f=open('test.json')
x=json.load(f)
f.close()
print(x)

test.jsonの内容:{"host": "127.0.0.1"、 "user": "jms"}


2

私はJavaのPropertiesクラスとほとんど同じようなpythonモジュールを作成しました(実際には、これは$ {variable-reference}を使用して定義済みのプロパティを参照できるようにするSpringのPropertyPlaceholderConfigurerのようなものです)

編集:コマンドを実行して、このパッケージをインストールできます(現在、Python 3でテストされています)。
pip install property

プロジェクトはGitHubでホストされています

例:(詳細なドキュメントはここにあります

my_file.propertiesファイルで次のプロパティが定義されているとしましょう

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

上記のプロパティをロードするコード

from properties.p import Property

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

my_file.propertiesファイルに次のプロパティが定義されているとしますfoo =私は素晴らしいですbar = $ {chocolate} -bar chocolate = fudge上記のプロパティをロードするコードprop = Property()prop.load( 'path / to / my_file .properties ')prop.get(' foo ')#私は素晴らしいですprop.get(' bar ')#fudge-bar
Anand Joshi

完了しました。それがお役に立て
Anand Joshi

2

プロパティファイルのセクションからすべての値を簡単な方法で読み取る必要がある場合:

あなたのconfig.propertiesファイルレイアウト:

[SECTION_NAME]  
key1 = value1  
key2 = value2  

あなたがコーディングする:

   import configparser

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

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

これにより、キーが設定ファイルと同じである辞書とそれに対応する値が得られます。

details_dict は:

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

ここで、key1の値を取得します。 details_dict['key1']

すべてを一度だけ設定ファイルからそのセクションを読み取るメソッドに入れます(プログラムの実行中にメソッドが初めて呼び出されるとき)。

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

次に、上記の関数を呼び出して、必要なキーの値を取得します。

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

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

上記のアプローチを拡張して、セクションごとに自動的に読み取り、次にセクション名とそれに続くキー名でアクセスします。

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

アクセスするために:

config_dict = get_config_section()

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

(ここで、「DB」は設定ファイルのセクション名で、「port」は「DB」セクションのキーです。)


1

以下の2行のコードは、Pythonリスト内包表記を使用して「javaスタイル」プロパティファイルをロードする方法を示しています。

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

詳細については、以下の投稿をご覧 くださいhttps://ilearnonlinesite.wordpress.com/2017/07/24/reading-property-file-in-python-using-comprehension-and-generators/


コードはファイルオブジェクトを閉じません。また、リンクのみの回答は歓迎されません。
aristotll 2017

このソリューションでは、複数行の値や等号を含む値は対象外です。
Konstantin Tarashchanskiy 2017

1

argparseでパラメーター "fromfile_prefix_chars"を使用して、以下のように構成ファイルから読み取ることができます---

temp.py

parser = argparse.ArgumentParser(fromfile_prefix_chars='#')
parser.add_argument('--a')
parser.add_argument('--b')
args = parser.parse_args()
print(args.a)
print(args.b)

設定ファイル

--a
hello
--b
hello dear

コマンドを実行

python temp.py "#config"

0

次のようにConfigParserを使用してこれを行いました。コードは、BaseTestが配置されているのと同じディレクトリにconfig.propというファイルがあることを前提としています。

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

これは私がファイルを解析して、コメントをスキップする環境変数として設定し、キー値以外の行を追加してhg:dを指定するスイッチを追加したものです

  • -hまたは--help使用法の要約を出力する
  • -cコメントを識別する文字を指定
  • -s propファイルのキーと値の間のセパレータ
  • 解析する必要があるプロパティファイルを指定します。例:python EnvParamSet.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 __name__ == "__main__":
                main(sys.argv[1:])

0

LightbendはTypesafe Configライブラリをリリースしました。これは、プロパティファイルを解析し、JSONベースの拡張機能もいくつか含みます。LightbendのライブラリはJVM専用ですが、広く採用されているようで、Pythonを含む多くの言語にポートがあります。https//github.com/chimpler/pyhocon


0

@mvallebrの変更されたコードである次の関数を使用できます。プロパティファイルのコメントを尊重し、空の改行を無視して、単一のキー値を取得できます。

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

これでうまくいきます。

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

この重複した投稿を削除してください。ところで私はあなたの他のものを
賛成しました

0

私はconfigparserアプローチに従いましたが、それは私にとって非常にうまくいきました。1つのPropertyReaderファイルを作成し、そこで構成パーサーを使用して、各セクションに対応するプロパティを準備しました。

** Python 2.7を使用

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

読み取ったスキーマファイルの内容:

from PropertyReader import *

class ReadSchema:

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

.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

これはiniファイルで、プロパティファイルにはセクションヘッダーがありません
Akshay

0

Pythonモジュールで辞書を作成し、すべてをモジュールに格納してアクセスします。次に例を示します。

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

これにアクセスするには、次のようにします。

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

1
いくつかのコードサンプルを共有することを強くお勧めします。今のところ、あなたの答えは非常に貧弱です
ニコライ・シェフチェンコ

@NikolayShevchenko書式設定が悪いため申し訳ありません。私は私の答えを更新しました
Vineet Singh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.