Cách tốt nhất để sử dụng tệp cài đặt trong Python là gì? [đóng cửa]


332

Tôi có một kịch bản dòng lệnh mà tôi chạy với rất nhiều đối số. Bây giờ tôi đã đến một điểm mà tôi có quá nhiều đối số và tôi cũng muốn có một số đối số ở dạng từ điển.

Vì vậy, để đơn giản hóa mọi thứ, tôi muốn chạy tập lệnh với tệp cài đặt thay thế. Tôi thực sự không biết những thư viện nào sẽ được sử dụng để phân tích tệp. Thực hành tốt nhất để làm điều này là gì? Dĩ nhiên tôi có thể tự mình đập thứ gì đó ra, nhưng nếu có thư viện nào đó, tôi sẽ nghe thấy.

Một vài 'nhu cầu':

  • Thay vì sử dụng pickletôi muốn nó là một tệp văn bản chuyển tiếp có thể dễ dàng đọc và chỉnh sửa.
  • Tôi muốn có thể thêm dữ liệu giống như từ điển trong đó, nghĩa là, một số hình thức lồng nhau cần được hỗ trợ.

Một tệp ví dụ giả đơn giản hóa:

truck:
    color: blue
    brand: ford
city: new york
cabriolet:
    color: black
    engine:
        cylinders: 8
        placement: mid
    doors: 2

6
Cú pháp cụ thể của tệp ví dụ này thực sự là YAML, hãy kiểm tra câu trả lời của Benson.
Skippy le Grand Gourou

Câu trả lời:


230

Bạn có thể có một mô-đun Python thông thường, giả sử config.py, như thế này:

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

và sử dụng nó như thế này:

import config
print config.truck['color']  

68
Đây là một ý tưởng khá tệ vì nếu bạn muốn cho phép người dùng có đặc quyền thấp chỉ có thể thay đổi các tệp cấu hình, theo cách này về cơ bản bạn cho phép họ lẻn vào mã đặc quyền.
nikolay

171
Cho phép người dùng "đặc quyền thấp" thay đổi cấu hình cho chương trình đặc quyền hơn có lẽ là một thiết lập đáng ngờ.
Xt

18
Bạn cũng có thể gặp phải các vấn đề trong việc đóng gói dự án của bạn để triển khai bằng một công cụ như py2app. Người dùng có thể không thể chỉnh sửa tệp cấu hình một khi nó được phân phối vì nó sẽ làm mất hiệu lực chữ ký của ứng dụng.
bschwagg

18
Nhược điểm chính với điều này (tùy chọn rất thuận tiện) là .pycác tệp có thể thực thi được, do đó, bất kỳ loại mã nào cũng có thể được chạy trong khi cố gắng tải cấu hình qua import. Điều đó không thể chấp nhận được từ quan điểm bảo mật.
Apalala

5
Không thể thực hiện một phiên bản này một cách an toàn với ast.literal_eval? docs.python.org/3/l Library / rast.html
André C. Andersen

168

Cấu hình mẫu bạn cung cấp thực sự là YAML hợp lệ . Trên thực tế, YAML đáp ứng tất cả các nhu cầu của bạn, được thực hiện bằng một số lượng lớn ngôn ngữ và cực kỳ thân thiện với con người. Tôi rất khuyên bạn nên sử dụng nó. Các dự án PyYAML cung cấp một mô-đun python đẹp, mà cụ YAML.

Để sử dụng mô-đun yaml cực kỳ đơn giản:

import yaml
config = yaml.safe_load(open("path/to/config.yml"))

3
yaml luôn là thứ tôi hướng đến; định dạng có thể từ đơn giản đến việc hỗ trợ mã python nhúng và thư viện tiêu chuẩn thực hiện rất nhiều công việc phân tích cú pháp và vệ sinh cho bạn.
Todor Minakov

14
Đã đồng ý. Đối với bạn hoặc người dùng viết YAML, đây là tài liệu tham khảo YAML tốt nhất mà tôi biết . Các tài liệu chính thức là tiếc một spec nhằm thực hiện, và không có gì khác, nhưng hướng dẫn Eevee là tuyệt vời.
Esteis

5
Đối với chúng tôi không quen biết, đó là pip3 install pyyamlđể làm cho nó sẵn sàng để nhập vào các kịch bản python.
dùng8675309

2
Coi chừng, yaml chỉ thân thiện nếu bạn giữ nó rất đơn giản, mặc định nó có vô số vấn đề, giáp với các tính năng không an toàn. Thay vào đó, hãy thử hitchdev.com/strictyaml như một cách thay thế an toàn theo mặc định.
Gringo Suave

107

Tôi thấy đây là cách hữu ích và dễ sử dụng nhất https://wiki.python.org/moin/ConfigParserExamples

Bạn chỉ cần tạo một "myfile.ini" như:

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

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

[Others]
Route: 66

Và lấy dữ liệu như:

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

20
Đối với Python 3 sử dụng các configparser mô-đun để thay thế (tất cả chữ thường)
Roland

2
Đây là giải pháp nhanh nhất, rõ ràng nhất và dễ thực hiện nhất, vì không có triển khai, chỉ sử dụng. :) Cảm ơn bạn!
Aleksandar

Điều này sẽ hỗ trợ từ điển lồng nhau như được hỏi trong câu hỏi mặc dù?
Jakub Bláha

54

Yaml và Json là các định dạng tệp đơn giản nhất và được sử dụng phổ biến nhất để lưu trữ cài đặt / cấu hình. PyYaml có thể được sử dụng để phân tích yaml. Json đã là một phần của python từ 2.5. Yaml là một superset của Json. Json sẽ giải quyết hầu hết các trường hợp sử dụng ngoại trừ chuỗi nhiều dòng trong đó yêu cầu thoát. Yaml cũng chăm sóc những trường hợp này.

>>> 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}

13
Mặc dù ít nhiều tương đương, json không gần như con người có thể đọc được như yaml. Vì cấu hình mẫu của anh ta thực sự hợp lệ, tôi nhấn mạnh rằng thay vì json.
Benson

23
Sử dụng "json.dump (config, fp, sort_keys = True, indent = 4)" sẽ cải thiện khả năng đọc.
phobie

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.