Strona główna Polish Python Coders Group
   Strona główna   Pomoc Zaloguj się Rejestracja  
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji

Aktualności:
Szukaj Szukaj
Strony: [1]   Do dołu
Drukuj
Wątek: Stałe w pliku configuracyjnym czy w głównym  (Przeczytany 393 razy)
« : 16:16 10/12/18 »
Cristof Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 4


Witajcie.

Taki problem.
Mam dużo stałych, zawsze je umieszczałem w odzielnym pliku, plik importowałem do głównego programu.
Np. plik conf.py
TIME = 5.

W głównym pliku importowałem import conf.py.

Jednakże teraz stałe buduje z wartości wejściowej. Oznacza to, że nie mogę umieścić ich w oddzielnym pliku, gdyż ten plik "nie widzi" wartości wejściowej. Wygląda to mniej więcej tak:
TIME = input*2, gdzie input pochodzi z zewnątrz, wchodząc do funkcji main() w pliku uruchomieniowym skryptu. Czy zatem te stałę umieścić w takim przypadku właśnie w funkcji main?
Pozdrawiam.

 
Zapisane
« Odpowiedz #1 : 21:29 10/12/18 »
Guaz Offline
Professional Python User

Zobacz profil
***

Reputacja: 64
Płeć: Mężczyzna
Wiadomości: 477


Cóż, problem da się rozwiązać w prosty sposób. Pytanie czy te stałe deklarujesz jako globalne (odradzane) czy jako lokalne dla main'a.

W pierwszej opcji chyba taki twór powinien działać:
plik conf.py
Kod
import sys
def time_var(arg):
   global TIME = arg
time_var(sys.argv[2])

plik main.py
Kod
from conf import *
 
def main(args):
   global TIME
   print(TIME)
   return 0

Chociaż osobiście odradzałbym używania zmiennych globalnych, ale niektórzy je lubią w kompozycji z dziwnymi błędami ¯\_(ツ)_/¯

Ja osobiście polecam użycie słownika ze zmiennymi konfiguracyjnymi:
plik conf.py
Kod
def configuration(args):
   collect = {}
   collect.update(time_var(args))
   return collect
 
def time_var(args):
   return {"TIME": args[1]}

plik main.py
Kod
from conf import *
 
def main(args):
   try:
       import conf
       config = conf.configuration(args)
   except ImportError:
       pass #Obsługa błędu gdy pliku nie ma.
   return 0
 
if __name__ == '__main__':
   import sys
   sys.exit(main(sys.argv))

To zagwarantuje poprawność kodu, i to już mogę powiedzieć że jestem pewien, że będzie działać, oczywiście można to też uprościć Uśmiech

Można też kombinować z update'owaniem locals. Ale nie polecam, to nie wychodzi.
Kod
def main(args):
   try:
       import conf
       locals().update(conf.configuration(args))
       print(locals())
       print(TIME) #Tu się pojawi błąd, bo taki update nie działa, więc lepiej wyłuskiwać wartości ze zmiennej słownikowej :).
   except ImportError:
       pass #Obsługa błędu gdy pliku nie ma.
   return 0
Zapisane

Python 3.5+ / Mint

Daje wędkę zamiast ryby. Chyba że ktoś się chce czegoś nauczyć, wtedy chętnie pomogę każdemu.
Za rybę niestety trzeba zapłacić Z politowaniem.
« Odpowiedz #2 : 21:52 10/12/18 »
Cristof Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 4


Nie wiem czy to trochę nie przekombinowane, ale rozumiem ideę.
Z tym, że ja w funkcji main zamiast mieć np. zahardcodowane TIME[0:2] chciałbym mieć np. godzina, załóżmy, że godzina = TIME[0:2].
Twój pomysł z dynamicznie zbudowanym słownikiem poprzez funckję, która zbuduje słownik gdy otrzyma input, jest bardzo fajny. Jednakże w main musiałbym używać zapisu slownik[godzina] gdyż (slownik[godzina] = TIME[0:2]) co nie wiem czy jest czytelne i czy nie lepiej w main użyć po prostu kilku zmiennych lokalnych i tyle.
Zapisane
« Odpowiedz #3 : 05:13 11/12/18 »
Guaz Offline
Professional Python User

Zobacz profil
***

Reputacja: 64
Płeć: Mężczyzna
Wiadomości: 477


Co do czytelności, słowniki w pythonie bardzo szybko doganiają każdego Uśmiech.
Zwłaszcza gdy zaczynasz korzystać z klas efektywnie i posługujesz się **kwargs.

Wszystko zależy od sytuacji, kiedy lepiej to zrobić lokalnie:
-Gdy używasz je tylko w jednym programie.
-Gdy chcesz być pewien że występują, bo są ci niezbędne.

Kiedy lepiej to zrobić słownikiem z importu:
-Gdy używasz je w wielu miejscach, wielu programach, bądź wielu funkcjach, które (może również) powinny móc je zmieniać (czyt. globalność zmian w słownikach, przykład kodu)
Kod
def main():
   d = {}
   change(d)
   print(d)
 
def change(dct):
   dct['a'] = 1
 
main()
-Gdy brak zmiennej w pliku konfiguracyjnym, nie powinien wywalać programu w eter, a sprytnie ją inicjalizować z domyślną wartością, bez rozległego sprawdzania 'czy istnieje'. Oraz uniknięcia szeroko zalecanego `try/except` na rzecz optymizacji kodu.
(przykład kodu)
Kod
def main():
   dct = {'a':1}
   dct['a'] = dct.get('a', 0)+1 #Jeśli istnieje 'a' to ją zwiększamy o jeden.
   dct['b'] = dct.get('b', 0)+1 #Jeśli nie istnieje 'b' zainicjalizuj ją z wartością zero i dodaj jeden.
   print(dct)
 
main()

Każda możliwość ma swoje wady, zalety i zastosowania. Wyjątkiem są bzdury Chichot.
Dobierz rozwiązanie do swoich potrzeb  Mrugnięcie
Zapisane

Python 3.5+ / Mint

Daje wędkę zamiast ryby. Chyba że ktoś się chce czegoś nauczyć, wtedy chętnie pomogę każdemu.
Za rybę niestety trzeba zapłacić Z politowaniem.
Strony: [1]   Do góry
Drukuj
Skocz do:  

© 2007 - 2019 Polish Python Coders Group
Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines | Theme by PixelSlot