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.