2013-05-22 16 views
5

Otrzymałem projekt od programisty, który opuścił naszą firmę. Niezbyt skomplikowane, ale nie wygląda to bardzo ładnie. Oto pytanie: Aplikacja ma kilka modułów, a jedna to "ustawienia", które przechowuje pewną aplikację. opcje (nie wszystkie możliwe opcje, powiedzmy tylko dwie: foo i bar). Kiedy aplikacja jest uruchomiona odczytuje opcje z linii poleceń (za pomocą argparse):Jak przechowywać ustawienia aplikacji w modułach

parser.add_argument('--foo', action='store_true') 
parser.add_argument('--bar', action='store_true') 
parser.add_argument('--baz', action='store_true') 

a następnie wykonuje on tę paskudną rzecz:

for name, val in parser.parse_args(sys.argv[1:])._get_kwargs(): 
    setattr(sys.modules['settings'], name, val) 

First: Myślę, że jest brudny, nie pythonic siekać . Po drugie, używanie takiego kodu jest po prostu niewygodne, ponieważ gdy potrzebuję użyć settings.baz, IDE skarży się, że nie istnieje. Intencją tego hacka jest uczynienie opcji analizowanych z wiersza poleceń dostępnymi we wszystkich modułach używanych dalej w aplikacji.

Myślę o czymś podobnym do singleton, ale użyłem go tylko raz w PHP i nie wiem, czy to poprawne rozwiązanie w Pythonie. A nawet jeśli tak, czy ktoś może pokazać przykład?

Jestem noobem w pytonie i na SO, proszę bądź dla mnie miły :) Dzięki.

p.s. Przepraszam za ewentualne błędy w moim English

+0

To jest duplikat. Odpowiedź na to pytanie została podana w tym temacie: http://stackoverflow.com/questions/15992387/python-settings-file –

+9

To nie jest duplikat - drugi dotyczy plików konfiguracyjnych, ten dotyczy konfiguracji modułu uruchomieniowego. –

Odpowiedz

4

modułów w Pythonie Singleton przedmioty, a za pomocą jednego, aby zapisać ustawienia używane przez inne moduły byłoby bardzo Pythonic

Druga linia "paskudnej rzeczy" to po prostu ustawienie atrybutów modułu o nazwie settings, a więc nie jest tak źle. Co gorsza, część pierwszego wiersza uzyskuje dostęp do prywatnego atrybutu obiektu argparse.Namespace zwróconego przez parser.parse_args() w celu uzyskania nazw i wartości ustawień przeanalizowanych z wiersza poleceń. Nieco lepszy sposób zrobić to może być coś takiego:

import settings # possibly empty .py file 

for name, val in vars(parser.parse_args(sys.argv[1:])).iteritems(): 
    setattr(settings, name, val) 

Jednak to nie rozwiąże problemów IDE IDE, ponieważ nie zna nazwę ustawień dodawanych dynamicznie. Prostym sposobem naprawy byłoby zdefiniowanie wszystkich możliwych atrybutów z pewnymi domyślnymi wartościami w module settings.py zamiast posiadania pustego.

Po raz pierwszy moduł to import ed dla niego wpis jest dodawany do słownika sys.modules z jego nazwą jako kluczem i instancją types.ModuleType jako wartością. Później import s najpierw sprawdzi, czy dany wpis już istnieje, i pominie przeładowanie pliku, jeśli tak - dlatego też twierdzę, że są to obiekty pojedynczo. Modyfikacje wprowadzone do jego atrybutów będą natychmiast widoczne dla innych modułów, które je zaimportowały lub zrobiły to później, więc jest to ogólnie dobry mechanizm udostępniania danych w aplikacji.

+1

Tego właśnie szukałem. Dodatkowo znalazłem ten [link] (http://docs.python.org/2/faq/programming.html#how-do-i-share-global-variables-across-modules), który właśnie potwierdza twoją odpowiedź. Jeśli chodzi o "paskudną rzecz" - masz rację, najbardziej mylącą rzeczą było użycie prywatnej metody. Dzięki za podpowiedź z 'vars'. I oczywiście dziękuję za szczegółowe wyjaśnienie, jak to wszystko działa. – user2410235

+0

To dobrze, że wyraźnie udokumentowali to użycie modułów w FAQ. Chociaż celem 'sys.modules' jest zapewnienie mechanizmu buforowania modułów, implementacja czyni je szczególnie dobrze przystosowanymi do wymiany danych pomiędzy modułami w aplikacji. – martineau

+1

FWIW Istnieje również sekcja zatytułowana [Jak udostępniać zmienne globalne w modułach?] (Https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across -Modules) w aktualnej dokumentacji Pythona 3, która ma tę samą rade (nazwijmy to "kanonicznym" sposobem na zrobienie tego typu rzeczy). – martineau

0
+1

Tak, widziałem ten moduł, ale raczej chodzi o fajny format konfiguracji niż to, czego potrzebuję. Właściwie to chodzi o to, jak współdzielić konfigurację we wszystkich modułach aplikacji. Bez względu na to, czy są to opcje z pliku konfiguracyjnego czy wiersza poleceń. Prawdopodobnie nie widzę rzeczy dowodowych i ten moduł ma to, czego potrzebuję, ale proszę zauważ, jestem noob w pytonie (i nie mam zbyt dużego doświadczenia w programowaniu). Byłoby miło, gdybyś mógł wskazać mi, jak go użyć w moim przypadku. – user2410235

Powiązane problemy