Czy w Pythonie mogę wywołać main () zaimportowanego modułu?

W Pythonie mam Moduł myModule.py gdzie definiuję kilka funkcji i main () , która pobiera kilka argumentów linii poleceń.

Zwykle wywołuję main () ze skryptu bash. Teraz chciałbym umieścić wszystko w małym pakiecie , więc pomyślałem, że może mógłbym zamienić mój prosty skrypt Basha w skrypt Pythona i umieścić go w pakiecie.

Więc jak właściwie wywołać funkcję main () myModule.py od funkcja main () z MyFormerBashScript.py mogę to zrobić? Jak przekazać do niego argumenty ?

Author: Ricky Robinson, 2013-01-24

6 answers

To tylko funkcja. Importuj i wywołaj:

import myModule

myModule.main()

Jeśli chcesz przeanalizować argumenty, masz dwie opcje:

  • Parsuje je w main(), ale przekazuje sys.argv jako parametr (cały kod poniżej w tym samym module myModule):

    def main(args):
        # parse arguments using optparse or argparse or what have you
    
    if __name__ == '__main__':
        import sys
        main(sys.argv[1:])
    

    Teraz możesz zaimportować i wywołać myModule.main(['arg1', 'arg2', 'arg3']) z innego innego modułu.

  • Have main() accept parameters that are already parsed (again all code in the myModule module):

    def main(foo, bar, baz='spam'):
        # run with already parsed arguments
    
    if __name__ == '__main__':
        import sys
        # parse sys.argv[1:] using optparse or argparse or what have you
        main(foovalue, barvalue, **dictofoptions)
    

    Oraz import i wywołanie myModule.main(foovalue, barvalue, baz='ham') gdzie indziej i przekazywanie w Pythonie argumentów w razie potrzeby.

Sztuczka polega na wykryciu, kiedy twój moduł jest używany jako skrypt; kiedy uruchamiasz plik Pythona jako skrypt Główny (python filename.py) nie jest używana Instrukcja import, więc python wywołuje ten moduł "__main__". Ale jeśli ten sam kod filename.py jest traktowany jako moduł (import filename), to python używa go jako nazwy modułu. W obu przypadkach ustawiona jest zmienna __name__, a testowanie pod nią informuje o tym, w jaki sposób Kod został uruchomiony.

 118
Author: Martijn Pieters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 13:44:50

Odpowiedź Martijena ma sens, ale brakowało w niej czegoś ważnego, co może wydawać się oczywiste dla innych, ale było dla mnie trudne do rozgryzienia.

W wersji, w której używasz argparse, musisz mieć tę linię w głównym korpusie.

args = parser.parse_args(args)

Normalnie, gdy używasz argparse tylko w skrypcie, po prostu piszesz

args = parser.parse_args()

I parse_args znajdują argumenty z linii poleceń. Ale w tym przypadku główna funkcja nie ma dostępu do argumentów wiersza poleceń, więc ty muszę powiedzieć argparse ' owi, jakie są argumenty.

Oto przykład

import argparse
import sys

def x(x_center, y_center):
    print "X center:", x_center
    print "Y center:", y_center

def main(args):
    parser = argparse.ArgumentParser(description="Do something.")
    parser.add_argument("-x", "--xcenter", type=float, default= 2, required=False)
    parser.add_argument("-y", "--ycenter", type=float, default= 4, required=False)
    args = parser.parse_args(args)
    x(args.xcenter, args.ycenter)

if __name__ == '__main__':
    main(sys.argv[1:])

Zakładając, że nazwałeś to mytest.py Aby go uruchomić, możesz wykonać dowolną z nich z linii poleceń

python ./mytest.py -x 8
python ./mytest.py -x 8 -y 2
python ./mytest.py 

Który zwraca odpowiednio

X center: 8.0
Y center: 4

Lub

X center: 8.0
Y center: 2.0

Lub

X center: 2
Y center: 4

Lub jeśli chcesz uruchomić z innego skryptu Pythona możesz zrobić

import mytest
mytest.main(["-x","7","-y","6"]) 

Który zwraca

X center: 7.0
Y center: 6.0
 43
Author: barry solomon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-10 17:14:31

To zależy. Jeśli główny kod jest chroniony przez if jak w:

if __name__ == '__main__':
    ...main code...

Wtedy Nie, Nie możesz zmusić Pythona do wykonania tego, ponieważ nie możesz wpływać na zmienną automatyczną __name__.

Ale gdy cały kod jest w funkcji, to może być w stanie. Try

import myModule

myModule.main()

Działa to nawet wtedy, gdy moduł zabezpiecza się __all__.

from myModule import * może nie sprawić, że main będzie widoczny dla ciebie, więc naprawdę musisz zaimportować sam moduł.

 26
Author: Aaron Digulla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 11:30:55

Ja też miałem taką samą potrzebę używając argparse. Chodzi o to, że parse_args funkcja instancji obiektu argparse.ArgumentParser domyślnie pobiera swoje argumenty z sys.args. Praca wokół, podążając za linią Martijna, polega na wyrażaniu tego wprost, dzięki czemu można zmienić argumenty, które przekazujesz parse_args jako pożądanie.

def main(args):
    # some stuff
    parser = argparse.ArgumentParser()
    # some other stuff
    parsed_args = parser.parse_args(args)
    # more stuff with the args

if __name__ == '__main__':
    import sys
    main(sys.argv[1:])

Kluczowym punktem jest przekazanie args do funkcji parse_args. Później, aby użyć głównego, po prostu rób, co mówi Martijn.

 3
Author: eguaio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 11:53:15

Odpowiedź, której szukałem, znalazła się tutaj: Jak używać argparse Pythona z argami innymi niż sys.argv?

Jeśli main.py i parse_args() jest napisane w ten sposób, to parsowanie może być wykonane ładnie

# main.py
import argparse
def parse_args():
    parser = argparse.ArgumentParser(description="")
    parser.add_argument('--input', default='my_input.txt')
    return parser

def main(args):
    print(args.input)

if __name__ == "__main__":
    parser = parse_args()
    args = parser.parse_args()
    main(args)

Następnie możesz wywołać main() i parsować do niego argumenty za pomocą parser.parse_args(['--input', 'foobar.txt']) w innym skrypcie Pythona:

# temp.py
from main import main, parse_args
parser = parse_args()
args = parser.parse_args([]) # note the square bracket
# to overwrite default, use parser.parse_args(['--input', 'foobar.txt'])
print(args) # Namespace(input='my_input.txt')
main(args)
 3
Author: Sida Zhou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 03:17:42

Zakładając, że próbujesz przekazać argumenty linii poleceń.

import sys
import myModule


def main():
    # this will just pass all of the system arguments as is
    myModule.main(*sys.argv)

    # all the argv but the script name
    myModule.main(*sys.argv[1:])
 0
Author: agoebel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 11:31:09