Pertahankan kasus di ConfigParser?

90

Saya telah mencoba menggunakan modul ConfigParser Python untuk menyimpan pengaturan. Untuk aplikasi saya, penting bagi saya untuk mempertahankan kasus setiap nama di bagian saya. Dokumen menyebutkan bahwa meneruskan str () ke ConfigParser.optionxform () akan menyelesaikannya, tetapi tidak berhasil untuk saya. Semua nama menggunakan huruf kecil. Apakah saya melewatkan sesuatu?

<~/.myrc contents>
[rules]
Monkey = foo
Ferret = baz

Pseudocode Python yang saya dapatkan:

import ConfigParser,os

def get_config():
   config = ConfigParser.ConfigParser()
   config.optionxform(str())
    try:
        config.read(os.path.expanduser('~/.myrc'))
        return config
    except Exception, e:
        log.error(e)

c = get_config()  
print c.options('rules')
[('monkey', 'foo'), ('ferret', 'baz')]
pojo
sumber

Jawaban:

114

Dokumentasinya membingungkan. Yang mereka maksud adalah ini:

import ConfigParser, os
def get_config():
    config = ConfigParser.ConfigParser()
    config.optionxform=str
    try:
        config.read(os.path.expanduser('~/.myrc'))
        return config
    except Exception, e:
        log.error(e)

c = get_config()  
print c.options('rules')

Ie menimpa optionxform, alih-alih memanggilnya; overriding dapat dilakukan dalam subclass atau dalam instance. Saat mengganti, setel ke fungsi (bukan hasil pemanggilan fungsi).

Saya sekarang telah melaporkan ini sebagai bug , dan sejak itu telah diperbaiki.

Martin v. Löwis
sumber
Terima kasih. Berhasil, dan saya setuju bahwa dokumennya membingungkan.
pojo
39

Bagi saya bekerja untuk mengatur optionxform segera setelah membuat objek

config = ConfigParser.RawConfigParser()
config.optionxform = str 
ulitosCoder
sumber
2
Bekerja dengan baik! (perhatikan bahwa di python 3 ini adalah nama kelas "configparser" (tidak ada huruf besar)
Noam Manos
1
@NoamManos: Anda mengacu pada nama modul (nama kelas masih ConfigParser ).
Jonas Byström
2
Perhatikan bahwa ini bekerja juga denganConfigParser.ConfigParser()
Jean-Francois T.
Memang. Berhasil. Sebaiknya disebutkan bahwa parameter ini pada dasarnya tidak terkait dengan RawConfigParser (), karena itu juga mendukung kelas ConfigParser (). Terima kasih sobat.
ivanleoncz
7

Tambahkan ke kode Anda:

config.optionxform = lambda option: option  # preserve case for letters
FooBar167
sumber
1
Ini tampaknya berfungsi untuk saya setidaknya di python 2.7 dan jauh lebih bersih daripada jawaban yang diterima. Terima kasih foo!
hrbdg
2
ini sama dengan jawaban atas skor - lihat baris config.optionxform=str:) alih-alih lamdba Anda @Martin v. Löwis menggunakan strfungsi tersemat
xuthus
@ xuthus - Memang, Anda dapat menggunakan 11 baris kode, bukan 1 baris. Sesukamu.
FooBar167
4

Saya tahu pertanyaan ini sudah terjawab, tetapi saya pikir beberapa orang mungkin menganggap solusi ini berguna. Ini adalah kelas yang dapat dengan mudah menggantikan kelas ConfigParser yang ada.

Diedit untuk memasukkan saran @ OozeMeister:

class CaseConfigParser(ConfigParser):
    def optionxform(self, optionstr):
        return optionstr

Penggunaannya sama dengan ConfigParser biasa.

parser = CaseConfigParser()
parser.read(something)

Ini agar Anda menghindari keharusan menyetel optionxform setiap kali Anda membuat yang baru ConfigParser, yang agak membosankan.

pohon es
sumber
Karena optionxformini hanyalah metode di RawConfigParser, jika Anda ingin membuat subkelas Anda sendiri, Anda harus mengganti metode pada subkelas daripada mendefinisikannya kembali sesuai contoh:class CaseConfigParser(ConfigParser): def optionxform(self, optionstr): return optionstr
OozeMeister
@OozeMeister ide bagus!
icedtrees
2

Peringatan:

Jika Anda menggunakan default dengan ConfigParser, yaitu:

config = ConfigParser.SafeConfigParser({'FOO_BAZ': 'bar'})

dan kemudian mencoba membuat parser peka huruf besar kecil dengan menggunakan ini:

config.optionxform = str

semua opsi Anda dari file konfigurasi akan menggunakan huruf kecil, tetapi FOO_BAZakan diubah menjadi huruf kecil.

Agar default juga menyimpan case mereka, gunakan subclass seperti dalam jawaban @icedtrees:

class CaseConfigParser(ConfigParser.SafeConfigParser):
    def optionxform(self, optionstr):
        return optionstr

config = CaseConfigParser({'FOO_BAZ': 'bar'})

Sekarang FOO_BAZsimpan kasusnya dan Anda tidak akan memiliki InterpolationMissingOptionError .

nidalpres
sumber