简体   繁体   English

如何读取 python 中的属性文件

[英]How to read properties file in python

I have a property file called Configuration.properties containing:我有一个名为Configuration.properties的属性文件,其中包含:

path=/usr/bin
db=mysql
data_path=/temp

I need to read this file and use the variable such as path , db , and data_path in my subsequent scripts.我需要阅读此文件并在后续脚本中使用pathdbdata_path等变量。 Can I do this using configParser or simply reading the file and getting the value.我可以使用 configParser 还是简单地读取文件并获取值来执行此操作。

Thanks in Advance.提前致谢。

For a configuration file with no section headers, surrounded by [] - you will find the ConfigParser.NoSectionError exception is thrown.对于没有节头的配置文件,用[]包围 - 你会发现抛出ConfigParser.NoSectionError异常。 There are workarounds to this by inserting a 'fake' section header - as demonstrated in this answer .通过插入“假”部分标题可以解决此问题- 如本答案所示

In the event that the file is simple, as mentioned in pcalcao's answer , you can perform some string manipulation to extract the values.如果文件很简单,如pcalcao 的回答中所述,您可以执行一些字符串操作来提取值。

Here is a code snippet which returns a dictionary of key-value pairs for each of the elements in your config file.这是一个代码片段,它返回配置文件中每个元素的键值对字典。

separator = "="
keys = {}

# I named your file conf and stored it 
# in the same directory as the script

with open('conf') as f:

    for line in f:
        if separator in line:

            # Find the name and value by splitting the string
            name, value = line.split(separator, 1)

            # Assign key value pair to dict
            # strip() removes white space from the ends of strings
            keys[name.strip()] = value.strip()

print(keys)

If you need to read all values from a section in properties file in a simple manner:如果您需要以简单的方式从属性文件中的某个部分读取所有值:

Your config.properties file layout :您的config.properties文件布局:

[SECTION_NAME]  
key1 = value1  
key2 = value2  

You code:你编码:

   import configparser

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

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

This will give you a dictionary where keys are same as in config file and their corresponding values.这将为您提供一个字典,其中的键与配置文件中的键及其对应的值相同。

details_dict is : details_dict是:

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

Now to get key1's value : details_dict['key1']现在获取 key1 的值: details_dict['key1']

Putting it all in a method which reads that section from config file only once(the first time the method is called during a program run).将所有内容放在一个方法中,该方法仅从配置文件中读取该部分一次(在程序运行期间第一次调用该方法)。

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

Now call the above function and get the required key's value :现在调用上面的函数并获取所需的键值:

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

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

Extending the approach mentioned above, reading section by section automatically and then accessing by section name followed by key name.扩展上述方法,自动逐节读取,然后按节名和键名访问。

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

To access:访问:

config_dict = get_config_section()

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

(here 'DB' is a section name in config file and 'port' is a key under section 'DB'.) (这里'DB'是配置文件中的一个部分名称,'port'是'DB'部分下的一个键。)

I like the current answer.我喜欢当前的答案。 AND... I feel like there is a cleaner way to do it in the "Real World".而且......我觉得在“真实世界”中有一种更清洁的方法。 Using the section header feature is a MUST if you are doing a project of any size or scale, particularly in the realm of "multiple" environments.如果您正在执行任何规模或规模的项目,尤其是在“多”环境领域,则必须使用节标题功能。 I wanted to put it in here with well formatted copy-able code, using a robust real world example.我想把它和格式良好的可复制代码放在一起,使用一个健壮的现实世界的例子。 This is running in Ubuntu 14, but works cross platform:这在 Ubuntu 14 中运行,但跨平台工作:

Real World Simple Example真实世界的简单示例

An 'Environment-based' configuration “基于环境”的配置
Setup Example (Terminal):设置示例(终端):

cd ~/my/cool/project touch local.properties touch environ.properties ls -la ~/my/cool/project -rwx------ 1 www-data www-data 0 Jan 24 23:37 local.properties -rwx------ 1 www-data www-data 0 Jan 24 23:37 environ.properties cd ~/my/cool/project touch local.properties touch environ.properties ls -la ~/my/cool/project -rwx------ 1 www-data www-data 0 Jan 24 23:37 local.properties -rwx------ 1 www-data www-data 0 Jan 24 23:37environ.properties

Set good permissions设置好权限

>> chmod 644 local.properties
>> chmod 644 env.properties
>> ls -la
-rwxr--r-- 1 www-data www-data  0 Jan 24 23:37 local.properties
-rwxr--r-- 1 www-data www-data  0 Jan 24 23:37 environ.properties

Edit your properties files.编辑您的属性文件。

FILE 1: local.properties文件 1:local.properties

This is YOUR properties file, local to your machine and workspace, and contains sensitive data, don't push to version control!!!这是您的属性文件,位于您的机器和工作区本地,包含敏感数据,请勿推送到版本控制!!!

[global]
relPath=local/path/to/images              
filefilters=(.jpg)|(.png)

[dev.mysql]
dbPwd=localpwd
dbUser=localrootuser

[prod.mysql]
dbPwd=5tR0ngpwD!@#
dbUser=serverRootUser

[branch]
# change this to point the script at a specific environment
env=dev

FILE 2: environ.properties文件 2:environ.properties

This properties file is shared by everybody, changes are pushed to version control这个属性文件是大家共享的,更改被推送到版本控制

#----------------------------------------------------
# Dev Environment
#----------------------------------------------------

[dev.mysql]
dbUrl=localhost
dbName=db

[dev.ftp]
site=localhost
uploaddir=http://localhost/www/public/images

[dev.cdn]
url=http://localhost/cdn/www/images


#----------------------------------------------------
# Prod Environment
#----------------------------------------------------
[prod.mysql]
dbUrl=http://yoursite.com:80
dbName=db

[prod.ftp]
site=ftp.yoursite.com:22
uploaddir=/www/public/

[prod.cdn]
url=http://s3.amazon.com/your/images/

Python File: readCfg.py Python文件:readCfg.py

This script is a re-usable snippet to load a list of configuration files import ConfigParser import os此脚本是一个可重用的片段,用于加载配置文件列表import ConfigParser import os

# a simple function to read an array of configuration files into a config object
def read_config(cfg_files):
    if(cfg_files != None):
        config = ConfigParser.RawConfigParser()

        # merges all files into a single config
        for i, cfg_file in enumerate(cfg_files):
            if(os.path.exists(cfg_file)):
                config.read(cfg_file)

        return config

Python File: yourCoolProgram.py Python 文件:yourCoolProgram.py

This program will import the file above, and call the 'read_config' method这个程序将导入上面的文件,并调用'read_config'方法

from readCfg import read_config

#merge all into one config dictionary
config      = read_config(['local.properties', 'environ.properties'])

if(config == None):
    return

# get the current branch (from local.properties)
env      = config.get('branch','env')        

# proceed to point everything at the 'branched' resources
dbUrl       = config.get(env+'.mysql','dbUrl')
dbUser      = config.get(env+'.mysql','dbUser')
dbPwd       = config.get(env+'.mysql','dbPwd')
dbName      = config.get(env+'.mysql','dbName')

# global values
relPath = config.get('global','relPath')
filefilterList = config.get('global','filefilters').split('|')

print "files are: ", fileFilterList, "relative dir is: ", relPath
print "branch is: ", env, " sensitive data: ", dbUser, dbPwd

Conclusion结论

Given the above configuration, you can now have a script which completely changes environments by changing the [branch]env value in 'local.properties'.鉴于上述配置,您现在可以拥有一个通过更改“local.properties”中的 [branch]env 值来完全改变环境的脚本。 And this is all based on good configuration principles!而这一切都是基于良好的配置原则! Yaay!耶!

Yes, yes you can.是的,是的,你可以。

ConfigParser ( https://docs.python.org/2/library/configparser.html ) will give you a nice little structure to grab the values from out of the box, where doing by hand will require some string splitting, but for a simple format file, it's no big deal. ConfigParser ( https://docs.python.org/2/library/configparser.html ) 将为您提供一个很好的小结构来从开箱即用中获取值,手动操作将需要一些字符串拆分,但对于一个简单的格式文件,没什么大不了的。

Is the question "How do I read this file?".问题是“我如何阅读这个文件?”。

One liner for reading an unstructured properties file (no sections) while ignoring comments:一个用于读取非结构化属性文件(无节)而忽略注释的衬垫:

with open(props_file_path, "r", encoding="utf-8") as f:
    props = {e[0]: e[1] for e in [line.split('#')[0].strip().split('=') for line in f] if len(e) == 2}

Keeping it simple.保持简单。 Create a properties file of name=value pairs and save it as filename.py.创建名称=值对的属性文件并将其保存为 filename.py。 Then all you have to do is import it and reference the properties as name.value.然后您所要做的就是导入它并将属性引用为 name.value。 Here's how...就是这样...

My config file for an Oracle connection is called config.py and looks like this.我的 Oracle 连接的配置文件名为 config.py,如下所示。

username = "username"
password = "password"
dsn = "localhost/xepdb1"
port = 1521
encoding = "UTF-8"

So, in the Python all I have to do is...所以,在 Python 中,我所要做的就是......

import cx_Oracle
import config

conn = None
cursor = None

try:

    print("connecting...");

    conn = cx_Oracle.connect(config.username, config.password, config.dsn, encoding=config.encoding)

    cursor = conn.cursor()

    print("executing...");

    # don't put a ';' at the end of SQL statements!
    cursor.execute("SELECT * FROM employees")

    print("dumping...");

    for row in cursor:
        print(row[0])

except cx_Oracle.Error as error:
    print(error)
finally:
    print("finally...")
    if cursor:
        cursor.close()
    if conn:
        conn.close()

If you want to read a proeprties file in python, my first suggestion, which I am myself not following because I like Visual Code too much ...如果你想在 python 中读取一个 proeprties 文件,我的第一个建议,我自己没有遵循,因为我太喜欢 Visual Code ......

Is run your python on Jython.在 Jython 上运行你的 python。 And once you run python on Jython, you can trivially open a java util input stream to your data file.一旦您在 Jython 上运行 python,您就可以轻松地打开一个 java util 输入流到您的数据文件。 And using the java.utl.Properties you can call the load() api, and you are set to go.使用 java.utl.Properties 可以调用 load() api,然后就可以开始了。 So my recommendation is, do what is easiest, just start using the java runtime environment and jython along with it.所以我的建议是,做最简单的事情,开始使用 java 运行时环境和 jython。

By the way, I am of course using jython to run python.顺便说一句,我当然是使用 jython 来运行 python 的。 No questions on that.对此没有任何疑问。

But what I am not doing is using jython to debug python... sadly!但是我没有做的是使用 jython 来调试 python ......可悲的是! The problem for me is that I use microsft visual code for writing pythong, and then yeah ... then I am stuck to the my normal python installation.对我来说问题是我使用 microsft 可视化代码来编写 pythong,然后是的......然后我被困在我的正常 python 安装中。 Not an ideal world!不是理想的世界!

If this would be your situation.如果这就是你的情况。 Then you can go to plan (b) ... Try to not use JDK libraries and find an alternative else where.然后你可以去计划(b)......尽量不使用JDK库并在其他地方找到替代方案。

So here is sugestion.所以这里是sugestion。 This is a library that I found out and and that I am using for the effect of reading properties files.这是我发现的一个库,我正在使用它来读取属性文件。 https://pypi.python.org/pypi/jproperties/1.0.1#downloads https://pypi.python.org/pypi/jproperties/1.0.1#downloads

 from jproperties import Properties with open("foobar.properties", "r+b") as f: p = Properties() p.load(f, "utf-8") # Do stuff with the p object... f.truncate(0) p.store(f, encoding="utf-8")

So in the above code quote, you seen how they open properties file.所以在上面的代码引用中,你看到了他们如何打开属性文件。 Wipe it out, and write back again the properties into the file.擦除它,然后再次将属性写回到文件中。

You tread the properties object as dictionary object.您将属性对象视为字典对象。 And then you do stuff like:然后你做这样的事情:

myPropertiesTuple = propertiesObjec[myPropertyKey]

Be careful.当心。 When you use the above api and get a value for a key, that value is a PropertiesTuple.当您使用上述 api 并获取键的值时,该值是一个 PropertiesTuple。 It is a pair of (value,metadata).它是一对(值,元数据)。 So the value you would be hunting for you get it from myPropertiesTuple[0].因此,您要寻找的值可以从 myPropertiesTuple[0] 中获取。 Other then that, just read the documentation on the page the library works well.除此之外,只需阅读该库运行良好的页面上的文档。

I am using approach (b).我正在使用方法(b)。 If the advantage of using the java libraries at some point outweighs the advantage of being stuck to native python language simply so that I may debug on visual code.如果在某些时候使用 java 库的优势超过了坚持使用原生 python 语言的优势,以便我可以调试可视化代码。

I will I hear beat drop support for pure python runtime and comrpomise the code with hard dependencies jython runtime / java libararies.我将听到对纯 python 运行时的节拍支持,并使用硬依赖项 jython 运行时/java 库对代码进行妥协。 So far there is no need for it.到目前为止还没有必要。

So, blue bill or the red pill?那么,蓝色账单还是红色药丸?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM