Toon posts:

[python] CLI arguments/globale variabelen

Pagina: 1
Acties:

Vraag


  • Yucon
  • Registratie: December 2000
  • Laatst online: 08:21
Ik gebruik diverse Python scripts en er is iets waar ik niet goed uit kom. De documentatie die ik tot nu toe kon vinden richt zich op CLI arguments, configuration files of lokale/globale variabelen maar ik zoek juist naar hoe ik die op een nette manier kan combineren.

Ik begrijp dat ik in een configuratiefile de settings per omgeving zou kunnen vastleggen. Maar los van de keuze voor de omgeving zijn er nog wat settings die je via de CLI kan wijzigen waardoor je niet alles als constante in een config file kunt zetten, en daarnaast zorgen sommige CLI opties ook voor een override van zo'n waarde die je normaal in de configfile zet dus constanten vallen daarmee ook af. Voorbeeld: de dev omgeving moet normaal gesproken geen data versturen maar alleen loggen, tenzij expliciet aangegeven wordt dat dat wel moet gebeuren. Zo is het lijstje nog wel wat langer dan in het voorbeeld dus laten we even niet op de specifieke voorbeeldparameters ingaan.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
if __name__ == "__main__":
    for i, arg in enumerate(sys.argv):
        if (arg.upper() == '-ENV'):
            envI = i
        
        if (envI > 0 and i == (envI + 1)):
            currEnv = arg.upper()

        if (arg.upper() == '-SENDDATAENABLED'):
            sendDataEnabled = True

        if (arg.upper() == '-INCLUDECATEGORIES'):
            doIncludeCategories = True


Maar wat nu? Om bij elke functie call in het script een lijst van 20 settings als parameter mee te geven is ook weer zowat. Ik gebruik nu globale variabelen maar dat geldt over het algemeen ook niet als heel netjes. Net als eventueel tijdens runtime configfiles steeds maar wijzingen. Maar wat dan wel netjes is weet ik eigenlijk ook niet.

Eventueel dacht ik nog aan omgevingsvariabelen via os.environ. Maar binnen python zelf moet toch ook wel iets mogelijk zijn lijkt me?

Beste antwoord (via Yucon op 04-03-2021 15:37)


  • Hydra
  • Registratie: September 2000
  • Nu online
Yucon schreef op donderdag 4 maart 2021 @ 13:51:
Dan zit je toch nog steeds precies met de kern van m'n vraag? Hoe geef je die netjes door aan functies?
Die worden meestal in de keten doorgegeven via een of meer configuratie objecten. In frameworks die dependency injection voor je doen, gaat dat zegmaar automagisch.

In jouw geval kun je dus een yaml file inlezen (op basis van een argument beslis je welke) en daaruit bouw je een configuratieobject. Deze stuur je dan in de keten mee bij het opbouwen van je objectenstructuur / door de keten van functie calls. En of je dat nu vanuit een configfile leest of vanuit argumenten maakt niet zo veel uit.

De key hier is dus dependency injection.

[Voor 5% gewijzigd door Hydra op 05-03-2021 19:45]

https://niels.nu

Alle reacties


  • gekkie
  • Registratie: April 2000
  • Laatst online: 22:55
module zoals argparse gebruiken ?

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-03 16:42
laten we beginnen bij het gebruiken van een module als optparse: https://docs.python.org/3/library/optparse.html
Daaruit kun je dan een dictonary samenstellen van jouw opties, die dictionary zou je daarna kunnen updaten met andere onfiguratiemogelijkheden (en welke volgorde je dat doet is maar net wat jij belangrijker vindt natuurlijk)

Ook zin in een outdoor geek-fest? eth0.nl


  • Yucon
  • Registratie: December 2000
  • Laatst online: 08:21
gekkie schreef op donderdag 4 maart 2021 @ 13:29:
module zoals argparse gebruiken ?
dankje, ik ga gelijk kijken. Nadeel met dit soort dingen is dat je al snel in zoektermen verdwaalt

  • gekkie
  • Registratie: April 2000
  • Laatst online: 22:55
killercow schreef op donderdag 4 maart 2021 @ 13:30:
laten we beginnen bij het gebruiken van een module als optparse: https://docs.python.org/3/library/optparse.html
Daaruit kun je dan een dictonary samenstellen van jouw opties, die dictionary zou je daarna kunnen updaten met andere onfiguratiemogelijkheden (en welke volgorde je dat doet is maar net wat jij belangrijker vindt natuurlijk)
Die is decprecated (zie eerste regel, argparse wordt nu aangeraden).

  • gekkie
  • Registratie: April 2000
  • Laatst online: 22:55
Yucon schreef op donderdag 4 maart 2021 @ 13:30:
[...]
dankje, ik ga gelijk kijken. Nadeel met dit soort dingen is dat je al snel in zoektermen verdwaalt
"python parsing arguments" lijkt bij mij in diverse zoekmachines op argparse documentatie als eerste hit uit te komen (en verder ook nog wat links naar tutorials).

Dus ik ben ergens wel benieuwd waar je zelf dan opgezocht had ?

  • Yucon
  • Registratie: December 2000
  • Laatst online: 08:21
gekkie schreef op donderdag 4 maart 2021 @ 13:34:
[...]

"python parsing arguments" lijkt bij mij in diverse zoekmachines op argparse documentatie als eerste hit uit te komen (en verder ook nog wat links naar tutorials).

Dus ik ben ergens wel benieuwd waar je zelf dan opgezocht had ?
Hoe je de situatie afhandelt waarin 1 argument voor meerdere settings zorgt. Dus bijvoorbeeld -env = prod ervoor zorgt dat setting1, setting2 en setting3 op false gaan, setting4 op true en setting5 op "donkerblauw". In mijn script is een deel van die setting1 t/m 5 niet benaderbaar vanaf de CLI. Dus ik zocht op dingen als 'CLI arguments global variables" en dergelijke.

Ik ben nog bezig met de documentatie goed te bekijken, maar als ik het goed begrijp pakt argparse het anders aan en worden al die settings als een potentiële CLI parameter gezien. Dat is een heel andere insteek en verklaart ook gelijk waarom ik niets vond.

  • gekkie
  • Registratie: April 2000
  • Laatst online: 22:55
Lijkt mij dat je prima een bijvb YAML config file kunt inladen als dict en dan op basis van wat je met argpargse vanuit de CLI parsed die individuele settings op basis van een key in je config dict overrulen ?
Waarbij de te verkiezen configfile uiteraard ook een argument kan zijn (en dan is het de vraag of het nog echt nodig is om te overrulen met cli opties ?

Afhankelijk van wat je precies wilt zijn er vele wegen naar Rome (er vanuitgaande dat je überhaupt naar Rome wilt natuurlijk ;) )

[Voor 41% gewijzigd door gekkie op 04-03-2021 13:47]


  • Yucon
  • Registratie: December 2000
  • Laatst online: 08:21
gekkie schreef op donderdag 4 maart 2021 @ 13:45:
Lijkt mij dat je prima een bijvb YAML config file kunt inladen als dict en dan op basis van wat je met argpargse vanuit de CLI parsed die individuele settings op basis van een key in je config dict overrulen ?
Waarbij de te verkiezen configfile uiteraard ook een argument kan zijn (en dan is het de vraag of het nog echt nodig is om te overrulen met cli opties ?
Dan zit je toch nog steeds precies met de kern van m'n vraag? Hoe geef je die netjes door aan functies? Als vuistregel probeer ik aan te houden dat globale variabelen eigenlijk alleen constanten mogen zijn. In m'n voorbeeld zijn setting1 t/m 5 niet constant. Daaruit afgeleid zouden ze dan ook niet globaal mogen zijn.

Als ik ze nu in een dictionary stop heb je nog steeds diezelfde situatie; ofwel die dict global maken, ofwel steeds overal als parameter meegeven.

Of is m'n idee dat zo'n global dict eigenlijk onwenselijk is gewoon onjuist?

edit:

Dat argparse is een goede tip en ik ga hem denk ik ook gebruiken, maar deze van stack overflow vind ik stiekem wel grappig.
The documentation for the argparse python module, while excellent I'm sure, is too much for my tiny beginner brain to grasp right now. I don't need to do math on the command line or meddle with formatting lines on the screen or change option characters. All I want to do is "If arg is A, do this, if B do that, if none of the above show help and quit".
met als een van de antwoorden
it's not you. it's argparse. it's trying to take you on a journey to the stars and doesn't care where you were headed.
Dat was eerlijk gezegd ook een beetje het idee dat ik had toen ik door de docs spitte.

[Voor 27% gewijzigd door Yucon op 04-03-2021 13:55]


Acties:
  • Beste antwoord
  • +1Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Nu online
Yucon schreef op donderdag 4 maart 2021 @ 13:51:
Dan zit je toch nog steeds precies met de kern van m'n vraag? Hoe geef je die netjes door aan functies?
Die worden meestal in de keten doorgegeven via een of meer configuratie objecten. In frameworks die dependency injection voor je doen, gaat dat zegmaar automagisch.

In jouw geval kun je dus een yaml file inlezen (op basis van een argument beslis je welke) en daaruit bouw je een configuratieobject. Deze stuur je dan in de keten mee bij het opbouwen van je objectenstructuur / door de keten van functie calls. En of je dat nu vanuit een configfile leest of vanuit argumenten maakt niet zo veel uit.

De key hier is dus dependency injection.

[Voor 5% gewijzigd door Hydra op 05-03-2021 19:45]

https://niels.nu


  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 22:38
In plaats van argparse kun je ook eens kijken naar click of typer; zijn net wat mooiere packages om CLI applicaties mee te bouwen.

Maar goed, als het alleen een config file meegeven is volstaat argparse natuurlijk ook wel prima.

P.S. Als je nog inspiratie zoekt voor een config classje: https://github.com/LFKoni...ger/blob/master/config.py

Werkt ook met hiërarchische yaml paden.

[Voor 29% gewijzigd door Morrar op 04-03-2021 18:56]


  • bwerg
  • Registratie: Januari 2009
  • Niet online

bwerg

Internettrol

Als je nog je configuratie-instellingen in globale variabele aan het stoppen bent, is de sleutel misschien vooral dat je die dingen in een object gaat stoppen die je aan de juiste functies/methoden meegeeft.

Dat dat mooi impliciet kan met dependency injection is een mooie bonus.

Heeft geen speciale krachten en is daar erg boos over.


  • Hydra
  • Registratie: September 2000
  • Nu online
bwerg schreef op vrijdag 5 maart 2021 @ 19:42:
[...]

Als je nog je configuratie-instellingen in globale variabele aan het stoppen bent, is de sleutel misschien vooral dat je die dingen in een object gaat stoppen die je aan de juiste functies/methoden meegeeft.
Dat stukje zegmaar in de eerste zin in m'n reactie die je weggeknipt hebt? :)

https://niels.nu


  • bwerg
  • Registratie: Januari 2009
  • Niet online

bwerg

Internettrol

Hydra schreef op vrijdag 5 maart 2021 @ 19:45:
[...]


Dat stukje zegmaar in de eerste zin in m'n reactie die je weggeknipt hebt? :)
Dat stukje wat ik weggeknipt heb is meer de key dan het stukje dat je de key noemt, inderdaad, maar goed, dat is mierenneuken. ;)

Maar natuurlijk: uiteindelijk wil je beiden.

[Voor 4% gewijzigd door bwerg op 05-03-2021 22:00]

Heeft geen speciale krachten en is daar erg boos over.

Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee