Jaka jest najlepsza praktyka przy użyciu pliku ustawień w Pythonie? [Zamknięte]

332

Mam skrypt wiersza polecenia, który uruchamiam z wieloma argumentami. Doszedłem do momentu, w którym mam zbyt wiele argumentów i chcę też mieć kilka argumentów w formie słownika.

Aby uprościć rzeczy, chciałbym zamiast tego uruchomić skrypt z plikiem ustawień. Naprawdę nie wiem, jakich bibliotek użyć do parsowania pliku. Jaka jest najlepsza praktyka w tym zakresie? Mógłbym oczywiście sam wykuć coś, ale jeśli jest na to trochę biblioteki, jestem cały w uszach.

Kilka „żądań”:

  • Zamiast używać picklechciałbym, aby był to prosty plik tekstowy, który można łatwo czytać i edytować.
  • Chcę mieć możliwość dodawania do niej danych przypominających słownik, tzn. Powinna być obsługiwana jakaś forma zagnieżdżania.

Uproszczony pseudo przykładowy plik:

truck:
    color: blue
    brand: ford
city: new york
cabriolet:
    color: black
    engine:
        cylinders: 8
        placement: mid
    doors: 2
c00kiemonster
źródło
6
Konkretna składnia tego przykładowego pliku to tak naprawdę YAML, sprawdź odpowiedź Bensona.
Skippy le Grand Gourou

Odpowiedzi:

231

Możesz mieć zwykły moduł Python, powiedz config.py, w następujący sposób:

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

i użyj tego w ten sposób:

import config
print config.truck['color']  
dugres
źródło
69
Jest to dość zły pomysł, ponieważ chcesz zezwolić użytkownikom o niskich uprawnieniach jedynie na zmianę plików konfiguracyjnych, w ten sposób zasadniczo pozwalasz im na wkradanie się do uprzywilejowanego kodu.
nikolay
171
Zezwolenie użytkownikom o „niskich uprawnieniach” na zmianę konfiguracji dla bardziej uprzywilejowanego programu jest prawdopodobnie wątpliwą konfiguracją.
XTL,
18
Możesz również napotkać problemy z pakowaniem projektu do wdrożenia przy użyciu narzędzia takiego jak py2app. Użytkownik może nie być w stanie edytować pliku konfiguracyjnego po jego rozpowszechnieniu, ponieważ spowoduje to unieważnienie podpisu aplikacji.
bschwagg,
18
Główną wadą tej (w przeciwnym razie bardzo wygodnej opcji) jest to, że .pypliki są wykonywalne, więc każdy rodzaj kodu może zostać uruchomiony podczas próby załadowania konfiguracji import. Jest to niedopuszczalne z punktu widzenia bezpieczeństwa.
Apalala
5
Czy nie można tego zrobić w bezpieczny sposób ast.literal_eval? docs.python.org/3/library/ast.html#ast.literal_eval
André C. Andersen
169

Podana przykładowa konfiguracja jest w rzeczywistości poprawna YAML . W rzeczywistości YAML spełnia wszystkie Twoje wymagania, jest wdrożony w wielu językach i jest wyjątkowo przyjazny dla człowieka. Gorąco polecam korzystanie z niego. Projekt PyYAML zapewnia ładny moduł Pythona, który implementuje YAML.

Korzystanie z modułu yaml jest niezwykle proste:

import yaml
config = yaml.safe_load(open("path/to/config.yml"))
Benson
źródło
3
yaml to zawsze coś, do czego się zwracam; format może być od bardzo prostego do obsługi osadzonego kodu python, a standardowa biblioteka wykonuje ciężkie analizy składni i urządzeń sanitarnych.
Todor Minakov
15
Zgoda. Dla ciebie lub użytkowników piszących YAML, oto najlepsze referencje YAML, jakie znam . Oficjalna dokumentacja jest niestety spec celem realizatorów, i nic poza tym, ale przewodnik Eevee jest fantastyczne.
Esteis
5
Dla nas niewtajemniczonych jest pip3 install pyyamlto przygotowanie go do zaimportowania do skryptów Pythona.
user8675309,
2
Uważaj, yaml jest przyjazny tylko wtedy, gdy utrzymujesz go bardzo prosto, domyślnie ma mnóstwo problematycznych, graniczących z niebezpiecznymi funkcjami. Spróbuj hitchdev.com/strictyaml zamiast domyślnie bezpiecznej alternatywy.
Gringo Suave
106

Znalazłem to najbardziej przydatne i łatwe w użyciu https://wiki.python.org/moin/ConfigParserExamples

Po prostu tworzysz plik „myfile.ini”, taki jak:

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

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

[Others]
Route: 66

I pobierz dane, takie jak:

>>> 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'
Maviles
źródło
20
W przypadku Python 3 użyj zamiast tego modułu konfiguratora (wszystkie małe litery)
Roland
2
Jest to najszybsze, najczystsze i najłatwiejsze do wdrożenia rozwiązanie, ponieważ nie ma implementacji, tylko użycie. :) Dziękuję Ci!
Aleksandar,
Czy takie wsparcie zagnieżdżałoby jednak słowniki, o jakie pytano w pytaniu?
Jakub Bláha,
54

Yaml i Json to najprostsze i najczęściej używane formaty plików do przechowywania ustawień / konfiguracji. PyYaml może być użyty do parsowania yaml. Json jest już częścią Pythona od wersji 2.5. Yaml jest nadzbiorem Jsona. Json rozwiąże większość przypadków użycia, z wyjątkiem ciągów wieloliniowych, w których wymagane jest stosowanie znaku ucieczki. Yaml zajmuje się także tymi przypadkami.

>>> 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}
Anoop
źródło
13
Chociaż mniej więcej równoważny, Json nie jest tak czytelny dla człowieka jak yaml. Ponieważ jego przykładowa konfiguracja jest właściwie poprawna yaml, podkreśliłbym to zamiast json.
Benson
23
Użycie „json.dump (config, fp, sort_keys = True, indent = 4)” poprawia czytelność.
phobie