最全總結 | 聊聊 Python 數據處理全家桶(配置篇)

1.前言

在實際項目中,經常會接觸到各種各樣的配置文件,它可以增強項目的可維護性

常用配件文件的處理方式,包含:JSON、ini / config、YAML、XML 等

本篇文章,我們將聊聊 Python 數據處理全家桶之配置文件大總結

​2.JSON

Python 內置了 JSON 模塊,可以非常方便操作 JSON 數據

常見的 4 個方法分別是:

  • json.load(json_file)

    解析 JSON 文件,轉換爲 Python 中對應的數據類型

  • json.loads(json_string)

    解析 JSON 格式的字符串,結果爲 Python 中的字典

  • json.dump(python_content,file_path)

    將 Python 數據,包含:dict、list 寫入到文件中

  • json.dumps(python_dict)

    將 Python 中 dict 轉爲 JSON 格式的字符串

以下面這段 JSON 配置文件爲例:

#config.json
{
  "mysql": {
    "host": "198.0.0.1",
    "port": 3306,
    "db": "xh",
    "username": "root",
    "password": "123456",
    "desc": "Mysql配置文件"
  }
}

1、讀取配置文件

讀取配置文件有兩種方式,分別是:

使用 json.load() 直接讀取配置文件

或者,先讀取配置文件中的內容,然後使用 json.loads() 轉換爲 Python 數據類型

需要指出的是,面對複雜層級的 JSON 配置文件,可以利用 jsonpath 進行讀取;jsonpath 類似於 xpath,可以通過正則表達式快速讀取數據

import json

def read_json_file(file_path):
    """
    讀取json文件
    :param file_path:
    :return:
    """
    with open(file_path, 'r', encoding='utf-8') as file:

        # 讀取方式二選一
        # 方式一
        result = json.load(file)

        # 方式二
        # result = json.loads(file.read())

        # 解析數據
        host_mysql = result['mysql']['host']
        port_mysql = result['mysql']['port']
        db = result['mysql']['db']

        print('Mysql地址:', host_mysql, ",端口號:", port_mysql, ",數據庫:", db)
​
    return result

2、保存配置文件

使用 json 中的 json.dump() 方法,可以將一個字典寫入到 JSON 文件中

def write_content_to_json_file(output_file, content):
    """
    寫入到json文件中
    :param output_file:
    :param content:
    :return:
    """
    with open(output_file, 'w') as file:
        # 寫入到文件中
        # 注意:爲了保證中文能正常顯示,需要設置ensure_ascii=False
        json.dump(content, file, ensure_ascii=False)

content_dict = {
    'mysql': {
        'host': '127.0.0.1',
        'port': 3306,
        'db': 'xh',
        'username': 'admin',
        'password': '123456',
        'desc': 'Mysql數據庫'
    }
}

write_content_to_json_file('./output.json', content_dict)

3、修改配置文件

如果需要修改配置文件,只需要先從配置文件中讀出內容,然後修改內容,最後將修改後的內容保存的配置文件中即可

def modify_json_file():
    """
    修改json配置文件
    :return:
    """
    result = read_json_file('./config.json')

    # 修改
    result['mysql']['host'] = '198.0.0.1'

    write_content_to_json_file('./config.json', result)

3.ini/config

ini 配置文件和 config 配置文件的解析方式類似,僅僅是文件後綴不一致

這裏我們以 ini 配置文件爲例

# config.ini
[mysql]
host = 139.199.1.1
username = root
password = 123456
port = 3306

ini 文件由 3 部分組成,分別是:節點(Section)、鍵(Key)、值(Value)

常見的 Python 處理 ini 文件有兩種方式,包含:

  • 使用內置的 configparser 標準模塊

  • 使用 configobj第三方依賴庫

我們先來看看內置的 configparser 模塊

3.1.1 讀取配置文件

實例化一個 ConfigParser 解析對象,使用 read() 方法讀取 ini 配置文件

from configparser import ConfigParser

# 實例化解析對象
cfg = ConfigParser()

# 讀取ini文件內容
cfg.read(file_path)

使用 sections()函數,可以獲取所有的節點列表

# sections() 得到所有的section,並以列表的形式返回
sections = cfg.sections()
print(sections)

要獲取某一個節點下的所有鍵,可以使用 options(section_name) 函數

# 獲取某一個區域的所有key
# cfg.options(section_name)
keys = cfg.options('mysql')
print(keys)

通過 items(section_name) 函數,可以獲取某一個節點下的所有鍵值對

# 獲取某一個區域下的鍵值對
items = cfg.items("mysql")
print(items)

如果要獲取某一個節點下,某一個鍵下的值,使用 get(section_name,key_name) 函數即可

# 讀取某一個區域下的某一個鍵值
host = cfg.get("mysql", "host")
print(host)

3.1.2 寫入配置文件

和讀取配置文件類似,需要先實例化一個 ConfigParser 解析對象

首先,使用 add_section(section_name) 函數添加一個節點

# 加入節點和鍵值對
# 添加一個節點
cfg.add_section("redis")

然後,就可以使用 set(section_name,key,value) 函數往某一個節點添加鍵值對

# 往節點內,添加鍵值對
cfg.set("redis", "host", "127.0.0.1")
cfg.set("redis", "port", "12345")

最後,使用 write() 函數寫入到配置文件中去

# 寫入到文件中
cfg.write(open('./raw/output.ini', 'w'))

3.1.3 修改配置文件

修改配置文件的步驟是,讀取配置文件,然後通過 set(section_name,key,value) 進行修改操作,最後使用 write() 函數寫入到文件中即可

def modify_ini_file(file_path):
    """
    修改ini文件
    :return:
    """
    cfg.read(file_path)

    cfg.set("mysql", "host", "139.199.11.11")

    # 寫入
    cfg.write(open(file_path, "w"))

接着,我們聊聊使用 configobj 操作 ini 配置文件的流程

首先安裝 configobj 依賴庫

# 依賴
# pip3 install configobj

3.2.1 讀取配置文件

直接將 ini 配置文件路徑作爲參數,使用 ConfigObj 類構造一個對象

from configobj import ConfigObj

# 實例化對象
config = ConfigObj(file_path, encoding='UTF8')

查看源碼可以發現,ConfigObj 是 Section 節點的子類,而 Section 是 Dict 字典的子類

所以,可以直接通過鍵名 Key 獲取節點和鍵值

# <class 'configobj.ConfigObj'>
print(type(config))

# <class 'configobj.Section'>
print(type(config['mysql']))

# 節點
print(config['mysql'])

# 某一個鍵對應的值
print(config['mysql']

3.2.2 修改配置文件

只需要讀取配置文件,然後直接修改 ConfigObj 對象,最後使用 write() 方法,即可以達到修改配置文件的目的

def modify_ini_file(file_path):
    """
    修改ini文件
    :param file_path:
    :return:
    """
    # 讀取配置文件
    config = read_ini_file(file_path)

    # 直接修改
    config['mysql']['host'] = '139.199.1.1'

    # 刪除某個鍵值對
    try:
        del config['mysql']['db']
    except Exception as e:
        print('鍵不存在')
        pass

    # 寫入
    config.write()

3.2.3 寫入配置文件

寫入配置文件,首先需要實例化一個 ConfigObj 對象,傳入文件路徑

然後,設置節點、針對節點設置鍵值對

最後,調用 write() 方法,寫入到配置文件中

def write_to_ini_file(output):
    """
    寫入到ini文件中
    :param output:
    :return:
    """
    config = ConfigObj(output, encoding='UTF8')
    config['website'] = {}
    config['website']['url'] = "www.baidu.com"
    config['website']['name'] = "百度"

    # 保存
    config.write()

4.YAML

Python 操作 YAML 文件,常見的 2 種方式分別是:pyyaml、ruamel.yaml

使用 pip 安裝依賴

# 安裝依賴
# 方式一
pip3 install pyyaml

# 方式二
pip3 install ruamel.yaml

下面以一個簡單的 YAML 配置文件爲例,通過兩種方式進行說明

# 水果
Fruits:
  # 蘋果
  - Apple:
      name: apple
      price:  1
      address:  廣東
  # 桔子
  - Orange:
      name: orange
      price:  3
      address:  湖南
  # 香蕉
  - Banana:
      name: banana
      price:  2
      address:  海南

我們先來看看 pyyaml

4.1.1 讀取配置文件

首先,讀取配置文件,使用 yaml.safe_load() 加載數據,獲取的數據類型是字典

import yaml

with open(file_path, "r") as file:
    data = file.read()

    # safe_load() 讀取配置文件
    # 結果數據類型:dict
    result = yaml.safe_load(data)

    print(result)

接着,就可以通過 YAML 配置文件的層級關係,獲取鍵值

# 3、獲取yaml中的值
name = result['Fruits'][0]['Apple']['name']
price = result['Fruits'][0]['Apple']['price']
address = result['Fruits'][0]['Apple']['address']
print("名稱:", name, ",price:", price, ",address:", address)

4.1.2 寫入配置文件

使用 YAML 中的 dump() 方法,可以將一個字典寫入到 YAML 配置文件中

需要注意的是,爲了保證中文寫入能正常顯示,需要配置 allow_unicode=True

def write_to_yaml_file(content, file_path):
    """
    寫入到yaml文件中
    :param content:
    :param file_path:
    :return:
    """

    # 寫入到文件中
    with open(file_path, 'w', encoding='utf-8') as file:
        yaml.dump(content, file, default_flow_style=False, encoding='utf-8', allow_unicode=True)

# 定義一個字典
content = {
   "websites": [{"baidu": {'url': "www.baidu.com", 'name': '百度', "price": 100}},{"alibaba": {'url': "www.taobao.com", 'name': '淘寶', "price": 200}},{"tencent": {'url': "www.tencent.com", 'name': '騰訊', "price": 300}},]
}

write_to_yaml_file(content, "./raw/new.yaml")

4.1.3 修改配置文件

和修改 ini 文件類型,先讀取配置文件,然後修改字典中的內容,最後使用上面的寫入方法,即可以達到修改配置文件的目的

def modify_yaml_file():
    """
    修改yaml文件
    :return:
    """
    content = read_yaml_file('./raw/norm.yaml')
    print(content)

    # 修改dict
    content['Fruits'][0]['Apple']['price'] = 10086

    # 重新寫入到一個新的yaml文件中
    write_to_yaml_file(content, './raw/output.yaml')

接着,我們來聊聊使用 ruamel 操作 YAML 配置文件的流程

ruamel 是 pyyaml 的衍生版本,在傳統 pyyaml 的基礎上,增加了 RoundTrip 模式,保證 YAML 配置文件的讀寫順序一致

所以,在讀取、修改、寫入方式上和 pyyaml 類似

4.2.1 讀取配置文件

from ruamel import yaml

def read_yaml_file(file_path):
    """
    讀取yaml文件
    :param file_path:
    :return:
    """
    with open(file_path, 'r', encoding='utf-8') as file:
        data = file.read()

        # 解析yaml文件
        # 類型:ordereddict
        result = yaml.load(data, Loader=yaml.RoundTripLoader)

        name = result['Fruits'][0]['Apple']['name']
        price = result['Fruits'][0]['Apple']['price']
        address = result['Fruits'][0]['Apple']['address']
        print("名稱:", name, ",price:", price, ",address:", address)

    return result

4.2.2 寫入配置文件

def write_to_yaml_file(filepath, data):
    """
    寫入到yaml文件中
    :param filepath:
    :param data:
    :return:
    """
    with open(filepath, 'w', encoding='utf-8') as file:
        yaml.dump(data, file, Dumper=yaml.RoundTripDumper, allow_unicode=True)

4.2.3 修改配置文件

def modify_yaml_file():
    """
    修改yaml文件
    :return:
    """
    content = read_yaml_file('./raw/norm.yaml')

    print(content)

    # 修改dict
    content['Fruits'][0]['Apple']['price'] = 10086

    # 重新寫入到一個新的yaml文件中
    write_to_yaml_file('./raw/output.yaml', content)

5.XML

XML 作爲一種標記語言,被用來設計存儲和傳輸數據,很多項目經常使用 XML 作爲配置文件和數據傳輸類型

Python 內置的 xml 模塊 可以很方便地處理 XML 配置文件

以下面這段配置文件爲例:

<?xml version="1.0" encoding="utf-8"?>
<dbconfig>
    <mysql>
        <host>127.0.0.1</host>
        <port>3306</port>
        <dbname>test</dbname>
        <username>root</username>
        <password>4355</password>
    </mysql>
</dbconfig>

首先,使用 xml.dom.minidom.parser(file_path) 解析配置文件,利用 documentElement 屬性獲取 XML 根節點

import xml.dom.minidom

# 讀取配置文件
dom = xml.dom.minidom.parse("./raw.xml")

# 利用 documentElement 屬性獲取 XML 根節點
# 根節點
root = dom.documentElement

接着,使用 getElementsByTagName(tag_name) 方法,獲取某一節點

# 獲取mysql節點
node_mysql = root.getElementsByTagName('mysql')[0]

最後,使用 childNodes 屬性,遍歷節點的子 Node 節點,獲取節點的名稱和值

# 遍歷子節點,獲取名稱和值
for node in node_mysql.childNodes:
    # 節點類型
    # 1:Element
    # 2:Attribute
    # 3:Text
    # print(node.nodeType)
    if node.nodeType == 1:
        print(node.nodeName, node.firstChild.data)

6.最後

到此,Python 數據全家桶以全部完結!

我已經將文中全部源碼上傳到後臺,關注公衆號「 AirPython 」後回覆「 dball 」即可獲得全部源碼

如果你覺得文章還不錯,請大家 點贊、分享、留言下,因爲這將是我持續輸出更多優質文章的最強動力!

推薦閱讀
聊聊 Python 數據處理全家桶(Mysql 篇)
聊聊 Python 數據處理全家桶(Sqlite 篇)
聊聊 Python 數據處理全家桶(Redis 篇)
聊聊 Python 數據處理全家桶(Memc 篇)
聊聊 Python 數據處理全家桶(Mongo 篇)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章