Bảo tồn trường hợp trong ConfigParser?


90

Tôi đã cố gắng sử dụng mô-đun ConfigParser của Python để lưu cài đặt. Đối với ứng dụng của tôi, điều quan trọng là tôi phải giữ nguyên trường hợp của từng tên trong các phần của mình. Các tài liệu đề cập rằng việc chuyển str () tới ConfigParser.optionxform () sẽ thực hiện được điều này, nhưng nó không hoạt động với tôi. Các tên đều là chữ thường. Tui bỏ lỡ điều gì vậy?

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

Mã giả Python của những gì tôi nhận được:

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')]

Câu trả lời:


114

Tài liệu khó hiểu. Ý họ là thế này:

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')

Tức là ghi đè optionxform, thay vì gọi nó; ghi đè có thể được thực hiện trong một lớp con hoặc trong trường hợp. Khi ghi đè, hãy đặt nó thành một hàm (thay vì kết quả của việc gọi một hàm).

Bây giờ tôi đã báo cáo đây là một lỗi và nó đã được sửa.


Cảm ơn bạn. Nó hoạt động và tôi đồng ý rằng các tài liệu là khó hiểu.
pojo

39

Đối với tôi, tôi đã làm việc để đặt optionxform ngay sau khi tạo đối tượng

config = ConfigParser.RawConfigParser()
config.optionxform = str 

2
Hoạt động tuyệt vời! (lưu ý rằng trong python 3 nó là "configparser" tên lớp (không viết hoa)
Noam Manos

1
@NoamManos: Bạn đang đề cập đến tên mô-đun (tên lớp vẫn là ConfigParser ).
Jonas Byström

2
Lưu ý rằng nó cũng hoạt động vớiConfigParser.ConfigParser()
Jean-Francois T.

Thật. Nó hoạt động. Tốt khi đề cập rằng tham số này về cơ bản không được liên kết với RawConfigParser (), vì nó cũng hỗ trợ với lớp ConfigParser (). Cảm ơn anh bạn.
ivanleoncz

7

Thêm vào mã của bạn:

config.optionxform = lambda option: option  # preserve case for letters

1
Điều này dường như phù hợp với tôi ít nhất là trong python 2.7 và rõ ràng hơn nhiều so với câu trả lời được chấp nhận. Cảm ơn foo!
hrbdg

2
điều này giống với câu trả lời được ghi điểm cao nhất - xem dòng config.optionxform=str:) chỉ thay vì lamdba @Martin v. Löwis của bạn sử dụng strchức năng nhúng
xuthus

@xuthus - Thật vậy, bạn có thể sử dụng 11 dòng mã thay vì 1 dòng. Như bạn muốn.
FooBar167

4

Tôi biết câu hỏi này đã được trả lời, nhưng tôi nghĩ một số người có thể thấy giải pháp này hữu ích. Đây là lớp có thể dễ dàng thay thế lớp ConfigParser hiện có.

Đã chỉnh sửa để kết hợp đề xuất của @ OozeMeister:

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

Cách sử dụng giống như ConfigParser bình thường.

parser = CaseConfigParser()
parser.read(something)

Điều này giúp bạn tránh phải đặt optionxform mỗi khi tạo một cái mới ConfigParser, điều này khá tẻ nhạt.


Kể từ khi optionxformchỉ là một phương pháp trên RawConfigParser, nếu bạn đang đi để đi xa như tạo lớp con của riêng mình, bạn nên thay vì chỉ ghi đè lên các phương pháp trên lớp chứ không phải xác định lại nó mỗi instantiation:class CaseConfigParser(ConfigParser): def optionxform(self, optionstr): return optionstr
OozeMeister

@OozeMeister ý tưởng tuyệt vời!
icedtrees

2

Cảnh báo:

Nếu bạn sử dụng giá trị mặc định với ConfigParser, tức là:

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

và sau đó cố gắng làm cho bộ phân tích cú pháp phân biệt chữ hoa chữ thường bằng cách sử dụng:

config.optionxform = str

tất cả các tùy chọn của bạn từ (các) tệp cấu hình sẽ giữ nguyên dạng của chúng, nhưng FOO_BAZsẽ được chuyển đổi thành chữ thường.

Để có các giá trị mặc định cũng giữ nguyên trường hợp của chúng, hãy sử dụng phân lớp như trong câu trả lời @icedtrees:

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

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

Bây giờ FOO_BAZsẽ giữ nguyên trường hợp của nó và bạn sẽ không có InterpolationMissingOptionError .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.