2010-07-10 36 views
17

Thông thường, tôi mã như sau để có được một mục cụ thể trong một biến như sauĐọc tất cả các nội dung trong file ini vào từ điển với Python

try: 
    config = ConfigParser.ConfigParser() 
    config.read(self.iniPathName) 
except ConfigParser.MissingSectionHeaderError, e: 
    raise WrongIniFormatError(`e`) 

try: 
    self.makeDB = config.get("DB","makeDB") 
except ConfigParser.NoOptionError: 
    self.makeDB = 0 

Có cách nào để đọc tất cả các nội dung trong một cuốn từ điển python ?

Ví dụ

 
[A] 
x=1 
y=2 
z=3 
[B] 
x=1 
y=2 
z=3 

được viết vào

 
val["A"]["x"] = 1 
... 
val["B"]["z"] = 3 

Trả lời

26

Tôi đề nghị subclassing ConfigParser.ConfigParser (hoặc SafeConfigParser, & c) để truy cập một cách an toàn "bảo vệ" thuộc tính (tên bắt đầu bằng gạch đơn - "private" sẽ là tên bắt đầu với hai dấu gạch dưới, không phải để được truy cập ngay cả trong lớp con ...):

import ConfigParser 

class MyParser(ConfigParser.ConfigParser): 

    def as_dict(self): 
     d = dict(self._sections) 
     for k in d: 
      d[k] = dict(self._defaults, **d[k]) 
      d[k].pop('__name__', None) 
     return d 

này mô phỏng logic thông thường của phân tích cú pháp cấu hình, và được đảm bảo để làm việc trong tất cả các phiên bản của Python, nơi có một module ConfigParser.py (lên đến 2.7, đó là cuối cùng của loạt 2.* - biết rằng sẽ không có tương lai Python 2.any phiên bản là cách compati khả năng sinh sản có thể được đảm bảo ;-).

Nếu bạn cần hỗ trợ các phiên bản Python 3.* tương lai (tối đa 3.1 và có thể sắp tới 3.2 nó sẽ ổn, chỉ cần đổi tên mô-đun thành tất cả chữ thường configparser thay vì khóa học) có thể cần một số sự chú ý/tinh chỉnh nhiều năm xuống đường, nhưng tôi không mong đợi bất cứ điều gì lớn.

23

tôi quản lý để có được một câu trả lời, nhưng tôi hy vọng có phải là một một tốt hơn.

dictionary = {} 
for section in config.sections(): 
    dictionary[section] = {} 
    for option in config.options(section): 
     dictionary[section][option] = config.get(section, option) 
+2

Tôi nghĩ rằng đây là một giải pháp rất tốt, tại sao không phải là bạn hài lòng với nó? –

+2

Đây phải là câu trả lời vì nó giải quyết được vấn đề mà không phải sử dụng thuộc tính "riêng" "_sections". Và, tất nhiên, nếu người ta cần sử dụng một OrderedDict, chỉ cần sử dụng nó thay cho dict thường xuyên. – SizzlingVortex

+1

Thay thế 'từ điển' bằng' defaultdict (dict) 'sẽ loại bỏ việc tạo dict trung gian. – noxdafox

10

Dữ liệu cá thể cho ConfigParser được lưu trữ nội bộ dưới dạng một mệnh đề lồng nhau. Thay vì tạo lại nó, bạn chỉ có thể sao chép nó.

>>> import ConfigParser 
>>> p = ConfigParser.ConfigParser() 
>>> p.read("sample_config.ini") 
['sample_config.ini'] 
>>> p.__dict__ 
{'_defaults': {}, '_sections': {'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B':   {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}, '_dict': <type 'dict'>} 
>>> d = p.__dict__['_sections'].copy() 
>>> d 
{'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}} 

Edit:

Alex Martelli của solution là sạch hơn, mạnh mẽ hơn, và đẹp hơn. Trong khi đây là câu trả lời được chấp nhận, tôi khuyên bạn nên sử dụng cách tiếp cận của mình để thay thế. Xem bình luận của mình để giải pháp này để biết thêm thông tin.

+4

Tôi luôn ghê tởm khi truy cập tên thuộc tính được bảo vệ ("bắt đầu bằng dấu gạch dưới") (và biến chứng vô lý khi đi qua '__dict__' không giúp gì cả -' d = p._sections.copy() 'là chính xác tương đương, đơn giản hơn và trực tiếp hơn). Đó là lý do tại sao tôi đề xuất trong câu trả lời của tôi thay thế việc sử dụng một lớp con thay thế - các lớp con là _expected_ để truy cập các thuộc tính được bảo vệ của lớp cơ sở. Trong C++, điều này được thực thi; trong Python, nó không phải là, nhưng đó là bởi vì người dùng có nghĩa vụ phải được xử lý kỷ luật đủ để không _need_ thực thi ;-). –

1

Làm thế nào để phân tích cú pháp tệp ini trong py?

import ConfigParser 
config = ConfigParser.ConfigParser() 
config.read('/var/tmp/test.ini') 
print config.get('DEFAULT', 'network') 

đâu tập tin test.ini chứa:

[DEFAULT] 
network=shutup 
others=talk 
6

Tôi biết rằng câu hỏi này đã được hỏi 5 năm trước đây, nhưng hôm nay tôi đã thực hiện dict hiểu này thingy:

parser = ConfigParser() 
parser.read(filename) 
confdict = {section: dict(parser.items(section)) for section in parser.sections()} 
0

Một điều nữa cần lưu ý là, ConfigParser chuyển đổi các giá trị khóa thành chữ thường do đó trong trường hợp bạn đang chuyển đổi các mục cấu hình thành từ điển chéo kiểm tra các yêu cầu của bạn. Tôi phải đối mặt với một vấn đề vì điều này. Đối với tôi, tôi đã có phím lạc đà, do đó, phải thay đổi một số mã khi tôi bắt đầu sử dụng từ điển thay vì tệp.Phương pháp ConfigParser.get() chuyển nội bộ sang chữ thường.

-1

từ https://wiki.python.org/moin/ConfigParserExamples

def ConfigSectionMap(section): 
dict1 = {} 
options = Config.options(section) 
for option in options: 
    try: 
     dict1[option] = Config.get(section, option) 
     if dict1[option] == -1: 
      DebugPrint("skip: %s" % option) 
    except: 
     print("exception on %s!" % option) 
     dict1[option] = None 
return dict1 
Các vấn đề liên quan