Apa praktik terbaik menggunakan file pengaturan di Python? [Tutup]

332

Saya memiliki skrip baris perintah yang saya jalankan dengan banyak argumen. Saya sekarang sampai pada titik di mana saya memiliki terlalu banyak argumen, dan saya ingin memiliki beberapa argumen dalam bentuk kamus juga.

Jadi untuk mempermudah, saya ingin menjalankan skrip dengan file pengaturan sebagai gantinya. Saya tidak benar-benar tahu perpustakaan apa yang digunakan untuk parsing file. Apa praktik terbaik untuk melakukan ini? Tentu saja saya bisa menuntaskan sesuatu, tetapi jika ada perpustakaan untuk ini, saya tidak keberatan.

Beberapa 'tuntutan':

  • Daripada menggunakan picklesaya ingin itu menjadi file teks lurus ke depan yang dapat dengan mudah dibaca dan diedit.
  • Saya ingin dapat menambahkan data seperti kamus di dalamnya, yaitu, beberapa bentuk sarang harus didukung.

File contoh semu yang disederhanakan:

truck:
    color: blue
    brand: ford
city: new york
cabriolet:
    color: black
    engine:
        cylinders: 8
        placement: mid
    doors: 2
c00kiemonster
sumber
6
Sintaks khusus file contoh ini sebenarnya adalah YAML, periksa jawaban Benson.
Skippy le Grand Gourou

Jawaban:

231

Anda dapat memiliki modul Python biasa, katakan config.py, seperti ini:

truck = dict(
    color = 'blue',
    brand = 'ford',
)
city = 'new york'
cabriolet = dict(
    color = 'black',
    engine = dict(
        cylinders = 8,
        placement = 'mid',
    ),
    doors = 2,
)

dan gunakan seperti ini:

import config
print config.truck['color']  
dugres
sumber
69
Ini adalah ide yang sangat buruk seolah-olah Anda ingin mengizinkan pengguna yang memiliki hak istimewa rendah untuk dapat mengubah file konfigurasi saja, dengan cara ini Anda pada dasarnya memungkinkan mereka untuk menyelinap dalam kode istimewa.
nikolay
172
Mengizinkan pengguna "istimewa rendah" untuk mengubah konfigurasi untuk program yang lebih istimewa mungkin adalah pengaturan yang dipertanyakan.
XTL
18
Anda juga dapat mengalami masalah pengemasan proyek Anda untuk penyebaran menggunakan alat seperti py2app. Pengguna mungkin tidak dapat mengedit file konfigurasi setelah didistribusikan karena itu akan membatalkan tanda tangan aplikasi.
bschwagg
18
Kerugian utama dengan ini (jika tidak pilihan yang sangat nyaman) adalah bahwa .pyfile dapat dieksekusi, sehingga segala jenis kode dapat dijalankan saat mencoba memuat konfigurasi melalui import. Itu tidak dapat diterima dari sudut pandang keamanan.
Apalala
5
Tidak bisakah versi ini dilakukan dengan aman ast.literal_eval? docs.python.org/3/library/ast.html#ast.literal_eval
André C. Andersen
169

Konfigurasi sampel yang Anda berikan sebenarnya adalah YAML yang valid . Faktanya, YAML memenuhi semua permintaan Anda, diimplementasikan dalam sejumlah besar bahasa, dan sangat ramah terhadap manusia. Saya akan sangat menyarankan Anda menggunakannya. Proyek PyYAML menyediakan modul python yang bagus, yang mengimplementasikan YAML.

Untuk menggunakan modul yaml sangat sederhana:

import yaml
config = yaml.safe_load(open("path/to/config.yml"))
Benson
sumber
3
yaml selalu sesuatu yang saya beralih ke; formatnya bisa dari mati sederhana hingga mendukung kode python tertanam, dan pustaka standar melakukan pengangkatan parsing dan sanitasi untuk Anda.
Todor Minakov
15
Sepakat. Untuk Anda atau pengguna yang menulis YAML, berikut ini adalah referensi YAML terbaik yang saya tahu . The dokumentasi resmi sayangnya spec ditujukan untuk pelaksana, dan tidak ada lagi, tetapi Eevee ini panduan fantastis.
Esteis
5
Bagi kami yang belum tahu, pip3 install pyyamlartinya siap mengimpor ke skrip python.
user8675309
2
Hati-hati, yaml hanya ramah jika Anda membuatnya sangat sederhana, secara default ada banyak masalah, berbatasan dengan fitur yang tidak aman. Coba hitchdev.com/strictyaml sebagai alternatif lite yang aman secara default.
Gringo Suave
107

Saya menemukan ini yang paling berguna dan mudah digunakan https://wiki.python.org/moin/ConfigParserExamples

Anda cukup membuat "myfile.ini" seperti:

[SectionOne]
Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True

[SectionTwo]
FavoriteColor=Green
[SectionThree]
FamilyName: Johnson

[Others]
Route: 66

Dan mengambil data seperti:

>>> import ConfigParser
>>> Config = ConfigParser.ConfigParser()
>>> Config
<ConfigParser.ConfigParser instance at 0x00BA9B20>
>>> Config.read("myfile.ini")
['c:\\tomorrow.ini']
>>> Config.sections()
['Others', 'SectionThree', 'SectionOne', 'SectionTwo']
>>> Config.options('SectionOne')
['Status', 'Name', 'Value', 'Age', 'Single']
>>> Config.get('SectionOne', 'Status')
'Single'
Maviles
sumber
20
Untuk Python 3 gunakan modul configparser sebagai gantinya (semua huruf kecil)
Roland
2
Ini adalah solusi yang tercepat, paling jelas dan termudah untuk diterapkan, karena tidak ada implementasi, hanya penggunaan. :) Terima kasih!
Aleksandar
Akankah ini mendukung kamus bersarang seperti yang ditanyakan dalam pertanyaan?
Jakub Bláha
54

Yaml dan Json adalah format file paling sederhana dan paling umum digunakan untuk menyimpan pengaturan / konfigurasi. PyYaml dapat digunakan untuk mengurai yaml. Json sudah menjadi bagian dari python dari 2.5. Yaml adalah superset dari Json. Json akan menyelesaikan sebagian besar kasus penggunaan kecuali string multi-baris di mana melarikan diri diperlukan. Yaml menangani kasus-kasus ini juga.

>>> import json
>>> config = {'handler' : 'adminhandler.py', 'timeoutsec' : 5 }
>>> json.dump(config, open('/tmp/config.json', 'w'))
>>> json.load(open('/tmp/config.json'))   
{u'handler': u'adminhandler.py', u'timeoutsec': 5}
Anoop
sumber
13
Meskipun kurang lebih setara, json tidak dapat dibaca oleh manusia seperti halnya yaml. Karena konfigurasi sampelnya benar-benar valid yaml, saya akan menekankan bahwa alih-alih json.
Benson
23
Menggunakan "json.dump (config, fp, sort_keys = True, indent = 4)" meningkatkan keterbacaan.
phobie