Python의 특성 파일 (Java 특성과 유사)


137

다음과 같은 형식 ( .properties 또는 .ini )이 제공됩니다.

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

를 들어 자바속성 클래스는 그 위의 형식과 구문 분석 / 상호 작용에 제공 기능.

파이썬표준 라이브러리 (2.x)에 비슷한 것이 있습니까?

그렇지 않은 경우 다른 대안이 있습니까?


5
이것은 Java 질문이 아닙니다. Java 태그 제거를 롤백 한 이유는 무엇입니까?
BalusC

답변:


69

.ini 파일의 경우 .ini 파일 과 호환되는 형식을 제공하는 ConfigParser 모듈이 있습니다.

어쨌든 완전한 .properties 파일을 구문 분석하는 데 사용할 수있는 것은 없습니다.


10
: pyjavaproperties는 자이 썬 사용하지 않으려면 옵션을 것 같다 bitbucket.org/jnoller/pyjavaproperties
한스 - 크리스토프 슈타이너

2
Java 특성 파일은 .ini 파일과 동일하지 않습니다. pyjavaproperties가 정답입니다
igni

2
Alex Matelli는 여기에서 ConfigParser를 사용하여 .properties 파일을 구문 분석하는 쉬운 방법을 제안했습니다
.

bitbucket.org/jnoller/pyjavaproperties는 2010 년 이후로 유지 관리되지 않았습니다. python 3과 호환되지 않습니다. @pi로 연결된 솔루션을 사용하겠습니다.
codyzu

여기에 언급 된 곳이 없기 때문에 이것이 동일하지 않다는 것을 다시 추가하겠습니다. Java 또는 Py3에 대해 말할 수 없으며 간단한 키 / 값에서 작동 할 수 있습니다. 그러나 문자열 보간 구문은 다릅니다. 이 솔루션은 Python 형식을 제공합니다. % (string) s 동안 (예를 들어 Ant) $ {string}을 사용합니다. pymotw.com/2/ConfigParser
mpe

74

이 작업을 수행 할 수 있었지만 아무도이 작업 ConfigParser을 수행하는 방법에 대한 예를 보여주지 않았으므로 속성 파일의 간단한 파이썬 리더와 속성 파일의 예가 있습니다. 확장명은 여전히 .properties이지만 .ini 파일에서 볼 수있는 것과 비슷한 섹션 헤더를 추가해야했습니다. 약간의 끔찍한 일이지만 작동합니다.

파이썬 파일 : 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 모듈은 파이썬 3에서 configparser로 이름이 변경되었습니다.
Gursewak Singh

이것은 섹션을 포함하지 않기 때문에 .properties 파일이 아닌 .ini 파일 용이며 섹션 헤더를 찾지 못하면 configParser가 실패합니다. 또한 ini 파일에 섹션이 포함되어 있지 않을 수
있으므로이

65

자바 속성 파일은 종종 유효한 파이썬 코드입니다. myconfig.properties 파일의 이름을 myconfig.py로 바꿀 수 있습니다. 그런 다음 파일을 다음과 같이 가져 오십시오.

import myconfig

속성에 직접 액세스

print myconfig.propertyName1

11
아이디어가 마음에 들지만 점이 포함 된 속성 (예 : prop.name="val"이 경우 작동 하지 않음)에서는 작동하지 않습니다 .
maxjakob

36
A java properties file is valid python code: 나는 달라야한다. 일부 Java 특성 파일은 유효한 파이썬 코드를 전달하지만 모두는 아닙니다. @mmjj가 말했듯이 점은 문제입니다. 인용되지 않은 리터럴 문자열도 마찬가지입니다. -1.
Manoj Govindan

24
오히려 나쁜 생각 ... 깨지기 때문에. Java prop 파일은 "="대신 ":"을 허용합니다. 줄 연속 후에 공백을 먹는다. 그들은 문자열을 인용하지 않습니다. "유효하지 않은 파이썬"은 없습니다.
Dan H

2
Java 특성 파일은 일반적으로 유효한 파이썬 코드를 전달하지 않습니다. 한 가지 대안은 파이썬 파일에서 속성을 설정하고 유효한 파이썬을 사용하는 것입니다 (예 : MEDIA_ROOT = '/ foo') ...
danbgray

3
이것은 가장 좋은 해킹입니다. 속성이 변경되어 파일이 더 이상 유효한 파이썬이 아닌 나쁜 하루를 보낼 것입니다.
r_2

59

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 지금 당장 필요하며 대부분의 사용 사례 (모두는 아님)를 다루는 순수한 파이썬 솔루션 인 자체 솔루션을 구현하기로 결정했습니다.

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
최고의 노치 솔루션이며 정확히 내가 찾던 것입니다!
Russell

이 같은 항목과 같은 줄에 주석을 지원하지 않습니다 foo = "bar" # bat.
ThomasW

1
@ThomasW Java를 사실상의 표준으로 사용하는 경우 Properties # load는이 foo를 값이 있는 특성 으로 처리합니다 "bar" # bat.
bonh

1
이전 질문에 대한 답변을 게시 할 때 요점이 무엇이라고 생각하십니까? 요점은 이것을 직접 구현하는 대신 내 푸른 파이프 라인 중 하나에 복사하여 붙여 넣어 시간을 절약 할 수 있다는 것입니다. 그래서 감사합니다 :)
올드 스님

1
답을 사랑하십시오! 단지 내가 변경했다 인라인 주석을 처리하기 위해 만든 변경 l = line.strip()l = line.split(comment_char)[0].strip()하고있는 경우 만 확인 l과 함께 다음 줄에 오히려 값이 있습니다 if l:.
벤 Dalling

17

파일 형식의 옵션이 있다면 언급 한대로 .ini 및 Python의 ConfigParser를 사용하는 것이 좋습니다. Java .properties 파일과의 호환성이 필요한 경우 jprops 라는 라이브러리를 작성했습니다 . 우리는 pyjavaproperties를 사용하고 있었지만 다양한 제한이 발생하면 내 구현을 끝내게되었습니다. 유니 코드 지원 및 이스케이프 시퀀스 지원 향상을 포함하여 .properties 형식을 완벽하게 지원합니다. pyjavaproperties는 디스크의 실제 파일에서만 작동하는 반면 Jprops는 파일과 유사한 객체를 구문 분석 할 수 있습니다.


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

파이썬 코드 :

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의 파이썬 대체 도 참조하십시오 .


1
두 번째 링크의 경우 ... 더 이상 적극적으로 개발되지 않습니다. Jesse noller는이 레시피로 프로젝트를 만들었습니다. 저자는이 레시피를 사용하는 모든 사람에게 해당 프로젝트를 권장합니다. pypi.python.org/pypi/pyjavaproperties
Big Al


3

이것은 java.util.Propeties의 일대일 대체품입니다.

문서에서 :

  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)

dev 위치를 자주 변경하고 일부 공통 변수는 로컬 환경과 관련이있을 때 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 클래스와 거의 비슷한 파이썬 모듈을 만들었습니다 (실제로 $ {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 파일에 다음과 같은 속성이 정의되어 있다고 가정 해 봅시다. .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 List Comprehension을 사용하여 '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

이 솔루션에는 여러 줄 값이나 등호가 포함 된 값이 포함되지 않습니다.
Konstantin Tarashchanskiy

1

argparse와 함께 "fromfile_prefix_chars"매개 변수를 사용하여 아래와 같이 구성 파일에서 읽을 수 있습니다.

온도

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 주석을 식별하는 char을 지정하십시오.
  • -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는 속성 파일과 일부 JSON 기반 확장을 구문 분석 하는 Typesafe 구성 라이브러리를 출시했습니다 . 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']

이 중복 게시물을 삭제하십시오. btw 나는 당신의 다른 하나를
찬성했다

0

나는 configparser 접근법을 따랐고 그것은 나를 위해 아주 잘 작동했습니다. 하나의 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 파일입니다. properties 파일에는 섹션 헤더가 없습니다
Akshay

0

파이썬 모듈에서 사전을 만들고 모든 것을 저장하고 액세스하십시오 (예 :

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

이제 액세스하려면 다음을 수행하십시오.

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

1
일부 코드 샘플을 공유하는 것이 좋습니다. 지금 당신의 대답은 매우 가난합니다
Nikolai Shevchenko

@NikolayShevchenko 서식이 좋지 않아서 죄송합니다. 답변을 업데이트했습니다
Vineet Singh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.