Saya menggunakan ConfigParser
untuk membaca konfigurasi runtime dari sebuah skrip.
Saya ingin memiliki fleksibilitas untuk tidak memberikan nama bagian (ada skrip yang cukup sederhana; mereka tidak memerlukan 'bagian'). ConfigParser
akan mengeluarkan NoSectionError
pengecualian, dan tidak akan menerima file tersebut.
Bagaimana cara membuat ConfigParser mengambil (key, value)
tupel dari file konfigurasi tanpa nama bagian?
Misalnya:
key1=val1
key2:val2
Saya lebih suka tidak menulis ke file konfigurasi.
python
parsing
configuration-files
Escualo
sumber
sumber
Jawaban:
Alex Martelli memberikan solusi untuk digunakan
ConfigParser
untuk mengurai.properties
file (yang tampaknya merupakan file konfigurasi tanpa bagian).Solusinya adalah pembungkus seperti file yang secara otomatis akan memasukkan judul bagian tiruan untuk memenuhi
ConfigParser
persyaratan.sumber
Tercerahkan oleh jawaban ini oleh jterrace , saya menemukan solusi ini:
ini_str = '[root]\n' + open(ini_path, 'r').read() ini_fp = StringIO.StringIO(ini_str) config = ConfigParser.RawConfigParser() config.readfp(ini_fp)
EDIT untuk calon karyawan Google: Mulai Python 3.4+
readfp
sudah tidak digunakan lagi, danStringIO
tidak diperlukan lagi. Sebagai gantinya kita bisaread_string
langsung menggunakan :with open('config_file') as f: file_content = '[dummy_section]\n' + f.read() config_parser = ConfigParser.RawConfigParser() config_parser.read_string(file_content)
sumber
Anda dapat melakukan ini dalam satu baris kode.
Di python 3, tambahkan header bagian palsu ke data file konfigurasi Anda, dan teruskan ke
read_string()
.from configparser import ConfigParser parser = ConfigParser() with open("foo.conf") as stream: parser.read_string("[top]\n" + stream.read()) # This line does the trick.
Anda juga dapat menggunakan
itertools.chain()
untuk mensimulasikan tajuk bagian untukread_file()
. Ini mungkin lebih hemat memori daripada pendekatan di atas, yang mungkin berguna jika Anda memiliki file konfigurasi besar dalam lingkungan runtime yang dibatasi.from configparser import ConfigParser from itertools import chain parser = ConfigParser() with open("foo.conf") as lines: lines = chain(("[top]",), lines) # This line does the trick. parser.read_file(lines)
Di python 2, tambahkan header bagian palsu ke data file konfigurasi Anda, bungkus hasilnya dalam sebuah
StringIO
objek, dan teruskan kereadfp()
.from ConfigParser import ConfigParser from StringIO import StringIO parser = ConfigParser() with open("foo.conf") as stream: stream = StringIO("[top]\n" + stream.read()) # This line does the trick. parser.readfp(stream)
Dengan salah satu pendekatan ini, setelan konfigurasi Anda akan tersedia di
parser.items('top')
.Anda dapat menggunakan StringIO di python 3 juga, mungkin untuk kompatibilitas dengan interpreter python lama dan baru, tetapi perhatikan bahwa sekarang ada di dalam
io
paket danreadfp()
sekarang sudah usang.Atau, Anda dapat mempertimbangkan untuk menggunakan parser TOML daripada ConfigParser.
sumber
Anda dapat menggunakan pustaka ConfigObj untuk melakukannya dengan mudah: http://www.voidspace.org.uk/python/configobj.html
Diperbarui: Temukan kode terbaru di sini .
Jika Anda menggunakan Debian / Ubuntu, Anda dapat menginstal modul ini menggunakan manajer paket Anda:
Contoh penggunaan:
from configobj import ConfigObj config = ConfigObj('myConfigFile.ini') config.get('key1') # You will get val1 config.get('key2') # You will get val2
sumber
Cara termudah untuk melakukannya adalah dengan menggunakan parser CSV python, menurut saya. Berikut adalah fungsi baca / tulis yang mendemonstrasikan pendekatan ini serta test driver. Ini harus berfungsi asalkan nilainya tidak boleh multi-baris. :)
import csv import operator def read_properties(filename): """ Reads a given properties file with each line of the format key=value. Returns a dictionary containing the pairs. Keyword arguments: filename -- the name of the file to be read """ result={ } with open(filename, "rb") as csvfile: reader = csv.reader(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE) for row in reader: if len(row) != 2: raise csv.Error("Too many fields on row with contents: "+str(row)) result[row[0]] = row[1] return result def write_properties(filename,dictionary): """ Writes the provided dictionary in key-sorted order to a properties file with each line of the format key=value Keyword arguments: filename -- the name of the file to be written dictionary -- a dictionary containing the key/value pairs. """ with open(filename, "wb") as csvfile: writer = csv.writer(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE) for key, value in sorted(dictionary.items(), key=operator.itemgetter(0)): writer.writerow([ key, value]) def main(): data={ "Hello": "5+5=10", "World": "Snausage", "Awesome": "Possum" } filename="test.properties" write_properties(filename,data) newdata=read_properties(filename) print "Read in: " print newdata print contents="" with open(filename, 'rb') as propfile: contents=propfile.read() print "File contents:" print contents print ["Failure!", "Success!"][data == newdata] return if __name__ == '__main__': main()
sumber
csv
modul yang cerdas untuk menyelesaikanConfigParser
keluhan umum . Lebih mudah digeneralisasikan dan dibuat agar kompatibel dengan Python 2 & 3 .Setelah mengalami masalah ini sendiri, saya menulis pembungkus lengkap untuk ConfigParser (versi Python 2) yang dapat membaca dan menulis file tanpa bagian secara transparan, berdasarkan pendekatan Alex Martelli yang ditautkan pada jawaban yang diterima. Ini harus menjadi pengganti drop-in untuk penggunaan ConfigParser apa pun. Mempostingnya jika ada yang membutuhkannya menemukan halaman ini.
import ConfigParser import StringIO class SectionlessConfigParser(ConfigParser.RawConfigParser): """ Extends ConfigParser to allow files without sections. This is done by wrapping read files and prepending them with a placeholder section, which defaults to '__config__' """ def __init__(self, *args, **kwargs): default_section = kwargs.pop('default_section', None) ConfigParser.RawConfigParser.__init__(self, *args, **kwargs) self._default_section = None self.set_default_section(default_section or '__config__') def get_default_section(self): return self._default_section def set_default_section(self, section): self.add_section(section) # move all values from the previous default section to the new one try: default_section_items = self.items(self._default_section) self.remove_section(self._default_section) except ConfigParser.NoSectionError: pass else: for (key, value) in default_section_items: self.set(section, key, value) self._default_section = section def read(self, filenames): if isinstance(filenames, basestring): filenames = [filenames] read_ok = [] for filename in filenames: try: with open(filename) as fp: self.readfp(fp) except IOError: continue else: read_ok.append(filename) return read_ok def readfp(self, fp, *args, **kwargs): stream = StringIO() try: stream.name = fp.name except AttributeError: pass stream.write('[' + self._default_section + ']\n') stream.write(fp.read()) stream.seek(0, 0) return ConfigParser.RawConfigParser.readfp(self, stream, *args, **kwargs) def write(self, fp): # Write the items from the default section manually and then remove them # from the data. They'll be re-added later. try: default_section_items = self.items(self._default_section) self.remove_section(self._default_section) for (key, value) in default_section_items: fp.write("{0} = {1}\n".format(key, value)) fp.write("\n") except ConfigParser.NoSectionError: pass ConfigParser.RawConfigParser.write(self, fp) self.add_section(self._default_section) for (key, value) in default_section_items: self.set(self._default_section, key, value)
sumber
Jawaban Blueicefield menyebutkan configobj, tetapi lib aslinya hanya mendukung Python 2. Sekarang ia memiliki port yang kompatibel dengan Python 3+:
https://github.com/DiffSK/configobj
API belum berubah, lihat dok .
sumber