Python'daki özellikler dosyası (Java Properties'e benzer)


137

Aşağıdaki biçim verildiğinde ( .properties veya .ini ):

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

İçin Java orada Özellikleri sınıf yukarıdaki biçimi ile ayrıştırma / etkileştiği için teklifler işlevsellik.

Orada bir şey benzer mi piton 's standart kitaplığı (2.x)?

Değilse, başka hangi alternatiflerim var?


5
Bu bir Java sorusu değil. Java etiketi kaldırmayı neden geri aldınız?
BalusC

Yanıtlar:


69

.İni dosyaları için .ini dosyalarıyla uyumlu bir biçim sağlayan ConfigParser modülü vardır.

Her neyse, tam .properties dosyalarını ayrıştırmak için hiçbir şey yok, bunu yapmak zorundayken sadece jython kullanıyorum (komut dosyası hakkında konuşuyorum).


10
Jython'u kullanmak istemiyorsanız pyjavaproperties bir seçenek gibi görünüyor: bitbucket.org/jnoller/pyjavaproperties
Hans-Christoph Steiner

2
java özellikler dosyası .ini dosyasına eşdeğer değil. pyjavaproperties doğru cevaptır
igni

2
Alex Matelli, .properties dosyalarını ConfigParser ile burada ayrıştırmanın kolay bir yolunu önerdi stackoverflow.com/a/2819788/15274
pi.

bitbucket.org/jnoller/pyjavaproperties 2010 yılından bu yana korunmamıştır. Python 3 ile uyumlu değildir. @pi ile bağlantılı çözümleri kullanırdım.
codyzu

Burada hiçbir yerde bahsedilmediğinden, bunun aynı olmadığını tekrar ekleyeyim. Java veya Py3 için konuşamıyorum ve belki de basit anahtar / değerler için çalışır. Ancak dize enterpolasyonunun sözdizimi farklıdır. Bu çözüm, Python formatlama sağlar. % (string) s while (örneğin Ant için) $ {string} kullanırdım. pymotw.com/2/ConfigParser
mpe

74

Ben çalışmak için bunu başardı ConfigParser, hiç kimse bunun nasıl yapılacağı ile ilgili herhangi bir örnek gösterdi, bu yüzden burada bir özellik dosyası ve özellik dosyası örneği basit bir python okuyucu. Uzantının hala olduğunu unutmayın .properties, ancak .ini dosyalarında gördüklerinize benzer bir bölüm başlığı eklemek zorunda kaldım ... biraz piç kurmayı, ama işe yarıyor.

Python dosyası: PythonPropertyReader.py

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

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

Özellik dosyası: ConfigFile.properties

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

Daha fazla işlevsellik için şu adresi okuyun: https://docs.python.org/2/library/configparser.html


5
ConfigParser modülü Python 3'te configparser olarak yeniden adlandırıldı.
Gursewak Singh

Bu, .ini dosyaları içindir, bölüm içermedikleri için .properties dosyaları değildir ve herhangi bir bölüm üstbilgisi bulamazsa configParser başarısız olur. Ayrıca, ini dosyaları bölümler içermeyebilir, bu nedenle bu configParser hiç güvenilir görünmüyor
BiAiB

65

Bir java özellikleri dosyası genellikle geçerli python kodudur. Myconfig.properties dosyanızı myconfig.py olarak yeniden adlandırabilirsiniz. Ardından dosyanızı şu şekilde içe aktarın:

import myconfig

ve doğrudan özelliklere erişme

print myconfig.propertyName1

11
Fikri seviyorum, ama nokta içeren özellikler için çalışmıyor, yani prop.name="val"bu durumda işe yaramayacak.
maxjakob

36
A java properties file is valid python code: Farklı olmak zorundayım. Bazı Java özellik dosyaları geçerli python kodu için geçecek, ancak kesinlikle hepsi değil. @ Mmjj dediği gibi noktalar bir problemdir. Alıntılanmamış değişmez dizeler de öyle. -1.
Manoj Govindan

24
Oldukça Kötü Bir Fikir ... kırıldığı için. Java destek dosyaları "=" yerine ":" işlevine izin verir; hat devamından sonra boşluk yerler; onlar dizeleri alıntı yok. Bunların hiçbiri "geçerli Python" değildir.
Dan H

2
Java özellik dosyaları genel olarak geçerli python kodu için geçmez. Bir alternatif, sadece bir python dosyasında özelliklerinizi ayarlamak ve geçerli python kullanmaktır (örneğin: MEDIA_ROOT = '/ foo') ...
danbgray

3
Bu en iyi kaçınılması bir kesmek. Özellik değiştirdiğinizde ve dosya artık geçerli python olmadığında kötü bir gün geçireceksiniz.
r_2

59

Bunun çok eski bir soru olduğunu biliyorum, ama şimdi ihtiyacım var ve çoğu kullanım örneğini (hepsi değil) kapsayan kendi çözümüm olan saf bir python çözümü uygulamaya karar verdim:

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

Şu sepbiçime sahip dosyaları ayrıştırmak için ':' işaretini değiştirebilirsiniz :

key : value

Kod aşağıdaki gibi doğru satırları ayrıştırır:

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

Aşağıdakilerle ilgili bir karar alırsınız:

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

1
Birinci sınıf çözüm ve tam olarak aradığım şey!
Russell

Bunun, girişlerle aynı satırdaki yorumları desteklemediğini unutmayın foo = "bar" # bat.
ThomasW

1
@ThomasW Java'yı fiili standart olarak kullanıyorsak, Properties # load bunu foodeğere sahip bir özellik olarak görür "bar" # bat.
bonh

1
Eski bir soruya cevap göndermenin ne anlama geldiğini düşündün mü? Mesele şu ki, bunu kendim uygulamak yerine masmavi boru hattımdan birine kopyalayıp yapıştırarak zaman kazanabildim. çok teşekkürler :)
yaşlı keşiş

1
Cevabı seviyorum! Keşke değiştirmekti satır içi yorumları işlemek için yapılmış değiştirmek l = line.strip()için l = line.split(comment_char)[0].strip()ve o zaman sadece çek lile müteakip hattında yerine bir değere sahiptir if l:.
Ben Dalling

17

Dosya biçimleri seçeneğiniz varsa, .ini ve Python'un ConfigParser öğelerini belirtildiği gibi kullanmanızı öneririm. Java .properties dosyalarıyla uyumluluğa ihtiyacınız varsa bunun için jprops adlı bir kitaplık yazdım . Pyjavaproperties kullanıyorduk, ancak çeşitli sınırlamalarla karşılaştıktan sonra kendimi uyguladım. Unicode desteği ve kaçış dizileri için daha iyi destek de dahil olmak üzere .properties biçimi için tam desteğe sahiptir. Jprops dosya benzeri herhangi bir nesneyi ayrıştırırken pyjavaproperties yalnızca diskteki gerçek dosyalarla çalışır.


1
Sadece denedim. Tıkır tıkır çalışıyor. MattGood için +1!
Dan H

1
pip install ve bir kod örneği eklerseniz, cevabınız daha da iyi pip install jprops olacaktır, açık (yol) fp olarak: properties = jprops.load_properties (fp) print (properties)
Lastik Ördek

10

çok satırlı özellikleriniz ve çok basit bir gereksiniminiz yoksa, birkaç kod satırı sizin için çözebilir:

Dosya t.properties:

a=b
c=d
e=f

Python kodu:

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

Bu tam olarak özellikler değildir, ancak Python'un yapılandırma dosyalarını ayrıştırmak için güzel bir kütüphanesi vardır . Ayrıca şu tarife bakın: java.util.Properties için bir python değiştirme .


1
İkinci bağlantı için ... Bu artık aktif olarak geliştirilmiyor. Jesse noller, bu tariften burada mevcut olmayan bazı düzeltmelerle bir proje oluşturdu. Yazar bu projeyi bu tarifi kullanan herkese tavsiye eder. pypi.python.org/pypi/pyjavaproperties
Big Al


3

Bu , java.util'in bire bir değiştirilmesidir.

Dokümandan:

  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.readfpBurada tanımlanan dosya benzeri bir nesneyi kullanabilirsiniz -> https://docs.python.org/2/library/configparser.html#ConfigParser.RawConfigParser.readfp

readlineÖzellikler dosyanızın gerçek içeriğinden önce bölüm adı ekleyen geçersiz kılan bir sınıf tanımlayın .

Ben dicttanımlanan tüm özellikleri döndüren sınıfa paketlenmiş .

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

Bunu kullandım, bu kütüphane çok yararlı

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

Projemde yaptığım şey şu: Ben sadece projede kullandığım tüm ortak değişkenleri / özellikleri içeren properties.py adlı başka bir .py dosyası oluşturuyorum ve herhangi bir dosyada bu değişkenlere başvurmak gerekiyor

from properties import *(or anything you need)

Geliştirme konumlarını sık sık değiştirirken ve bazı ortak değişkenler yerel ortama nispeten göreceli olarak svn barışı korumak için bu yöntemi kullandım. Benim için iyi çalışıyor, ancak bu yöntemin resmi geliştirme ortamı vb. İçin önerileceğinden emin değilim.


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

Test.json içeriği: {"host": "127.0.0.1", "user": "jms"}


2

Neredeyse Java Properties sınıfına benzer bir python modülü oluşturduk (Aslında zaten tanımlanmış özelliğe başvurmak için $ {variable-reference} kullanmanıza izin veren PropertyPlaceholderConfigurer gibi)

DÜZENLEME: Bu paketi şu anda (şu anda python 3 için test edilmiştir) çalıştırarak yükleyebilirsiniz.
pip install property

Proje GitHub'da barındırılıyor

Örnek: (Ayrıntılı belgeleri burada bulabilirsiniz )

Diyelim ki my_file.properties dosyasında aşağıdaki özelliklere sahipsiniz

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

Yukarıdaki özellikleri yüklemek için kod

from properties.p import Property

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

Diyelim ki my_file.properties dosyasında aşağıdaki özelliklere sahip olduğunuzu varsayalım foo = Müthişim bar = $ {chocolate} -bar chocolate = fudge Yukarıdaki özellikleri yüklemek için kod prop = Property () prop.load ('path / to / my_file .properties ') prop.get (' foo ') # Ben müthiş prop.get (' bar ') # geçiştirme çubuğu
Anand Joshi

Bitti. Umarım yardımcı olur
Anand Joshi

2

Özellikler dosyasındaki bir bölümdeki tüm değerleri basit bir şekilde okumanız gerekiyorsa:

Kişisel config.propertiesdosya düzeni:

[SECTION_NAME]  
key1 = value1  
key2 = value2  

Siz kodu:

   import configparser

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

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

Bu, anahtarların yapılandırma dosyasındaki ve karşılık gelen değerleriyle aynı olduğu bir sözlük verecektir.

details_dict dır-dir :

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

Şimdi key1'in değerini almak için: details_dict['key1']

Hepsini bu bölümü yapılandırma dosyasından yalnızca bir kez okuyan bir yönteme koymak (yöntem bir program çalıştırılırken ilk kez çağrıldığında).

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

Şimdi yukarıdaki işlevi çağırın ve gerekli anahtarın değerini alın:

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

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

Yukarıda belirtilen yaklaşımı genişletmek, bölüm bölüm otomatik olarak okumak ve daha sonra bölüm adına ve ardından anahtar adına erişmek.

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

Erişmek için:

config_dict = get_config_section()

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

(burada 'DB', yapılandırma dosyasındaki bir bölüm adıdır ve 'port', 'DB' bölümünün altındaki bir anahtardır.)


1

Aşağıdaki 2 satır kod, 'java style' özellik dosyasını yüklemek için Python List Comprehension'ın nasıl kullanılacağını gösterir.

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

Ayrıntılar için lütfen aşağıdaki gönderiye bir göz atın https://ilearnonlinesite.wordpress.com/2017/07/24/reading-property-file-in-python-using-comprehension-and-generators/


Kod dosya nesnesini kapatmaz, ayrıca bağlantı sadece cevap hoş değil.
aristotll

Bu çözüm çok satırlı değerleri veya eşittir işareti içeren değerleri kapsamaz.
Konstantin Tarashchanskiy

1

yapılandırma dosyasından aşağıdaki gibi okumak için argparse ile "fromfile_prefix_chars" parametresini kullanabilirsiniz ---

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)

yapılandırma dosyası

--a
hello
--b
hello dear

Komutu çalıştır

python temp.py "#config"

0

Bunu aşağıdaki gibi ConfigParser kullanarak yaptım. Kod, BaseTest öğesinin yerleştirildiği dizinde config.prop adlı bir dosya olduğunu varsayar:

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

Bu dosyayı ayrıştırmak ve hg: d belirtmek için anahtarları ve anahtar olmayan değer satırları eklenen anahtarları atlayan env değişkenleri olarak yazmıştı.

  • -h veya --yardım kullanımı özetine yardım et
  • -c Yorumu tanımlayan karakter belirtin
  • -s Prop dosyasında anahtar ve değer arasındaki ayırıcı
  • ve ayrıştırılması gereken özellikler dosyasını belirtin örneğin: 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, özellik dosyalarını ve bazı JSON tabanlı uzantıları ayrıştıran Typesafe Config kitaplığını yayımladı . Lightbend'in kütüphanesi sadece JVM içindir, ancak yaygın olarak benimsenmiş gibi görünüyor ve şimdi Python da dahil olmak üzere birçok dilde bağlantı noktaları var: https://github.com/chimpler/pyhocon


0

Değiştirilmiş mvallebr kodu olan aşağıdaki işlevi kullanabilirsiniz. Özellikler dosya yorumlarına saygı gösterir, boş yeni satırları yok sayar ve tek bir anahtar değerinin alınmasına izin verir.

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

bu benim için çalışıyor.

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

Lütfen bu yinelenen yayını kaldırın. btw Ben diğerini upvote;)
javadba

0

Configparser yaklaşımını izledim ve benim için oldukça iyi çalıştı. Bir PropertyReader dosyası oluşturuldu ve her bir bölüme karşılık gelen ready özelliğe orada yapılandırma ayrıştırıcısı kullandı.

** Kullanılmış Python 2.7

PropertyReader.py dosyasının içeriği:

#!/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

Okuma şeması dosyasının içeriği:

from PropertyReader import *

class ReadSchema:

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

.Properties dosyasının içeriği:

[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

Bu bir ini dosyasıdır, özellikler dosyasında bölüm üstbilgisi yoktur
Akshay

0

python modülünüzde bir sözlük oluşturun ve her şeyi içine kaydedin ve erişin, örneğin:

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

Şimdi ona erişmek için şunları yapabilirsiniz:

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

1
Bazı kod örneklerinin paylaşılması önemle tavsiye edilir. Şimdilik cevabınız çok kötü
Nikolai Shevchenko

@NikolayShevchenko kötü biçimlendirme için özür dilerim, cevabımı güncelledim
Vineet Singh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.