Python操作YAML文件
今天維護某個外包專案,看到該專案有使用YAML套件,順便紀錄一下使用方式。
套件安裝
讀取YAML文件
假設有一個名為config.yaml的YAML文件,內容如下:
使用PyYAML庫中的safe_load方法來讀取這個文件:import yaml
with open('config.yaml', 'r', encoding = "utf-8") as file:
config = yaml.safe_load(file)
print(config)
補充: 在yaml也有一個
yaml.load函數,在官方說明上,此函數不安全,建議使用yaml.safe_load進行載入
不使用yaml.load函數進行載入的原因?
在前面有說不要使用yaml.load函數進行載入,主要是因為會yaml.load可能會引發的安全性問題,如下面範例
import yaml
from yaml import Loader
yaml_data = """
!!python/object/apply:eval
args: ['print("Hello World!")']
"""
yaml.load(yaml_data, Loader)
上面程式碼可以看到 yaml_data 中含有 !!python/object/apply:eval 的字串,可以讓 PyYMAL 在解析字串時,順便執行 Python 程式碼列印出 Hello World 字串,因為這個關係,使用yaml.load,是可以強制執行python程式碼,如果yaml的來源是不受信任來源(如:Internet),要使用 yaml.safe_load()會更安全 , 因為該方法只會讀取 YAML 標準定義的 tags,可以避免造成上面不安全的問題。
以下是使用yaml.safe_load()的範例
import yaml
yaml_data = """
!!python/object/apply:eval
args: ['print("Hello World!")']
"""
try:
parsed_data = yaml.safe_load(yaml_data)
except yaml.YAMLError as e:
print(f"Error: {e}")
上述程式碼將會出現以下錯誤,代表其不接受 !!python/object/apply:eval tag:

寫入YAML文件
如果想要修改設定並保存回文件,可以使用dump方法,例如修改database底下的port參數:
config['database']['port'] = 3307
with open('config.yaml', 'w', encoding = "utf-8") as file:
yaml.dump(config, file)
寫入時中文亂碼的處理方式
當參數的設定值有含有中文內容時,在進行保存會導致中文變成亂碼(unicode編碼),以上面yaml內容舉例
database:
host: localhost
hostName: SuperComputer #這裡新增一個參數
port: 3306
username: user
password: pass
超級電腦保存
import yaml
#讀取yaml
with open('config.yaml', 'r', encoding="utf-8") as file:
config = yaml.safe_load(file)
#改寫hostName設定值
config['database']['hostName'] = "超級電腦"
#保存
with open('config.yaml', 'w', encoding="utf-8") as file:
yaml.dump(config, file)
我們看一下config.yaml檔案,可以看見hostname的值變成亂碼(unicode編碼)

要解決這個問題,需設定allow_unicode=true,即可正常顯示中文