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

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

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

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'

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}

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.