Je suis dans une situation un peu étrange où j'ai besoin d'une fonction Python à exécuter à partir d'un script, le script étant ensuite appelé à partir de mon code principal.
Je voulais utiliser le module sous-processus
, et savoir comment l'utiliser pour passer des arguments à un script pur, mais le fait est que je dois passer les arguments à la fonction Python imbriquée à l'intérieur, dont la plupart sont facultatifs et ont des valeurs par défaut.
Je pensais que arparse
m'aiderait d'une manière ou d'une autre.
Voici un exemple de ce que j'essaye:
## Some Argparse, which will hopefully help import argparse parser = argparse.ArgumentParser() ## All arguments, with only "follow" being required parser.add_argument('file_name', help='Name of resulting csv file') parser.add_argument('sub_name', help='Sub-name of resulting csv file') parser.add_argument('follow', help='Account(s) to follow', required=True) parser.add_argument('locations', help='Locations') parser.add_argument('languages', help='Languages') parser.add_argument('time_limit', help='How long to keep stream open') args = parser.parse_args() ## Actual Function def twitter_stream_listener(file_name=None, sub_name='stream_', auth = api.auth, filter_track=None, follow=None, locations=None, languages=None, time_limit=20): ... function code ... ... more function code ... ... ... ## End of script
3 Réponses :
Vous pouvez spécifier les valeurs par défaut dans la section argparse (si c'est ce que vous essayez d'accomplir):
$ ./test.py something $ ./test.py --argument='somethingelse' somethingelse $ ./test.py --arg2=123 something 123 $ ./test.py --arg2='ipsum' --argument='lorem' lorem ipsum
Appelez ensuite:
#!/usr/bin/python import argparse parser = argparse.ArgumentParser() parser.add_argument('--argument', default = 'something', type = str, help = 'not helpful') parser.add_argument('--arg2', default = None, type = str, help = 'not helpful') args = parser.parse_args() def foo(arg , arg2 ): print(arg) if not arg2 is None: print(arg2) foo(args.argument, args.arg2)
Est-ce utile?
Vous pouvez le faire comme ça:
python -m your_module_name follow_val --file_name sth1 --locations sth2
follow
sera le seul argument requis et le reste facultatif. Les optionnels doivent être fournis avec -
au début. Vous pouvez facilement utiliser le module avec sous-processus
si vous en avez besoin.
Exemple d'appel en ligne de commande:
import argparse ## Actual Function def twitter_stream_listener(file_name=None, sub_name='stream_', auth=api.auth, filter_track=None, follow=None, locations=None, languages=None, time_limit=20): # Your content here if __name__ == '__main__': parser = argparse.ArgumentParser() ## All arguments, with only "follow" being required parser.add_argument('follow', help='Account(s) to follow') parser.add_argument('--file_name', help='Name of resulting csv file') parser.add_argument('--sub_name', help='Sub-name of resulting csv file') parser.add_argument('--locations', help='Locations') parser.add_argument('--languages', help='Languages') parser.add_argument('--time_limit', help='How long to keep stream open') args = parser.parse_args() twitter_stream_listener(file_name=args.file_name, sub_name=args.sub_name, follow=args.follow, locations=args.locations, languages=args.languages, time_limit=args.time_limit)
Puisque je suis encore un peu novice dans les scripts Python, qu'est-ce que la section if __name__ == '__main__':
réalise ici? Ne pourrais-je pas simplement utiliser votre exemple sans cela?
Cette réponse stackoverflow l'expliquera beaucoup mieux que je ne pourrais le faire en un seul commentaire: stackoverflow.com/a/419185/3603682
Si vous transmettez des arguments à des fonctions, il vous suffit de les insérer dans la fonction lorsque vous les exécutez:
import argparse parser = argparse.ArgumentParser() parser.add_argument("-o", "--output_file_name", help="Name of resulting csv file") parser.add_argument("-s", "--sub_name", default="stream_", help="Sub-name of resulting csv file") parser.add_argument("-f", "--follow", help="Account(s) to follow", required=True) parser.add_argument("-loc", "--locations", default=None, help="Locations") parser.add_argument("-lan", "--languages", default=None, help="Languages") parser.add_argument("-t", "--time_limit", default=20, help="How long to keep stream open") options = parser.parse_args() # then just pass in the arguments when you run the function twitter_stream_listener(file_name=options.output_file_name, sub_name=options.sub_name, auth=api.auth, filter_track=None, follow=options.follow, locations=options.locations, languages=options.languages, time_limit=options.time_limit) # or, pass the arguments into the functions when defining your function def twitter_stream_listener_with_args(file_name=options.output_file_name, sub_name=options.sub_name, auth=api.auth, filter_track=None, follow=options.follow, locations=options.locations, languages=options.languages, time_limit=options.time_limit): # does something pass # then run with default parameters twitter_stream_listener_with_args()
argparse
prend juste les chaînes desys.argv
(ou une autre liste que vous passez explicitement àparse_args
) et vous donne l'objetargs
. Ce que vous faites avecargs
dépend de vous. Vous pouvez le traiter comme une variable globale, ou le passer comme argument supplémentaire àtwitter_stream_listener
, ou simplement passer les attributs individuels comme arguments si nécessaire.Votre code semble correct, recevez-vous des erreurs?
Êtes-vous sûr que vous devez utiliser
sous-processus
pour démarrer le programme A et exécuter la fonctionA.twitter_stream_listener ()
à l'intérieur? Une approche beaucoup plus simple serait d'avoir votre codeimporter A
et d'appelerA.twitter_stream_listener ()
directement.aaaakshat, je ne reçois aucune erreur, je ne sais pas comment structurer mon code pour envoyer mes arguments analysés à ma fonction. BoarGules, je voulais faire ça au début, mais ma fonction en question a été écrite par quelqu'un d'autre, et je ne sais pas comment la refactoriser pour me permettre de fermer ladite fonction à mi-chemin (sans affecter aucun autre processus dans le reste du noyau ), j'essaie donc de lui donner son propre sous-processus, qui semble plus facile à fermer à la volée.