В Python у меня есть модуль myModule.py, в котором я определяю несколько функций и main () , который принимает несколько аргументов командной строки.
Обычно я вызываю эту функцию main () из сценария bash. Теперь я хотел бы поместить все в небольшой пакет , поэтому я подумал, что, может быть, я смогу превратить свой простой сценарий bash в сценарий Python и поместить его в пакет.
Итак, как мне на самом деле вызвать функцию main () myModule.py из функции main () MyFormerBashScript.py? Могу я даже это сделать? Как мне передать ему какие-либо аргументы ?
myModule.main()
. что ты уже испробовал?subprocess
модуля?Ответы:
Это просто функция. Импортируйте его и назовите:
import myModule myModule.main()
Если вам нужно проанализировать аргументы, у вас есть два варианта:
Разберите их
main()
, но передайтеsys.argv
как параметр (весь код ниже в том же модулеmyModule
):def main(args): # parse arguments using optparse or argparse or what have you if __name__ == '__main__': import sys main(sys.argv[1:])
Теперь вы можете импортировать и вызывать
myModule.main(['arg1', 'arg2', 'arg3'])
из другого другого модуля.Есть
main()
принимать параметры, которые уже разобранные (опять весь код вmyModule
модуле):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)
и импортировать и вызывать в
myModule.main(foovalue, barvalue, baz='ham')
другом месте и передавать аргументы Python по мере необходимости.Уловка здесь состоит в том, чтобы определить, когда ваш модуль используется как скрипт; когда вы запускаете файл python в качестве основного скрипта (
python filename.py
), никакойimport
оператор не используется, поэтому python вызывает этот модуль"__main__"
. Но если тот жеfilename.py
код обрабатывается как module (import filename
), тогда python вместо этого использует его в качестве имени модуля. В обоих случаях переменная__name__
установлена, и тестирование с ее помощью сообщает вам, как выполнялся ваш код.источник
argparse
, поэтому, когда я вызываю скрипт с терминала, я использую$ python myModule -a input_a -b input_b --parameterC input_c
. Как это будет работать из кода Python? Вот чего я не смог найти простым поиском.Ответ Мартиджена имеет смысл, но в нем упускается что-то важное, что может показаться очевидным для других, но мне было трудно понять.
В версии, где вы используете argparse, вам необходимо, чтобы эта строка была в основном теле.
Обычно, когда вы используете argparse только в скрипте, вы просто пишете
и parse_args находят аргументы из командной строки. Но в этом случае основная функция не имеет доступа к аргументам командной строки, поэтому вы должны сообщить argparse, каковы аргументы.
Вот пример
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:])
Предполагая, что вы назвали этот mytest.py Чтобы запустить его, вы можете выполнить любое из этих действий из командной строки.
python ./mytest.py -x 8 python ./mytest.py -x 8 -y 2 python ./mytest.py
который возвращается соответственно
X center: 8.0 Y center: 4
или же
X center: 8.0 Y center: 2.0
или же
X center: 2 Y center: 4
Или, если вы хотите запустить из другого скрипта Python, вы можете сделать
import mytest mytest.main(["-x","7","-y","6"])
который возвращается
X center: 7.0 Y center: 6.0
источник
AttributeError: module 'sqlacodegen' has no attribute 'main'
Это зависит. Если основной код защищен
if
как в:if __name__ == '__main__': ...main code...
тогда нет, вы не можете заставить Python выполнить это, потому что вы не можете повлиять на автоматическую переменную
__name__
.Но когда весь код находится в функции, возможно, это удастся. Пытаться
import myModule myModule.main()
Это работает, даже если модуль защищает себя с помощью файла
__all__
.from myModule import *
может неmain
отображаться для вас, поэтому вам действительно нужно импортировать сам модуль.источник
import sys; module.main(sys.argv);
__main__
которое мне помогло, спасибо @AaronDigullaУ меня была такая же потребность в использовании
argparse
. Дело в том, чтоparse_args
функцияargparse.ArgumentParser
экземпляра объекта неявно принимает свои аргументы по умолчанию изsys.args
. Обход, следующий за строкой Martijn, состоит в том, чтобы сделать это явным, чтобы вы могли изменить аргументы, которые вы передаетеparse_args
как желаемое.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:])
Ключевым моментом является передача аргументов
parse_args
функции. Позже, чтобы использовать главное, вы просто делаете, как говорит Мартин.источник
Ответ, который я искал, был дан здесь: Как использовать python argparse с другими аргументами, кроме sys.argv?
Если
main.py
иparse_args()
написано таким образом, то синтаксический анализ может быть выполнен красиво# 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)
Затем вы можете вызвать
main()
и проанализировать аргументыparser.parse_args(['--input', 'foobar.txt'])
для него в другом скрипте Python:# 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)
источник
Предполагая, что вы также пытаетесь передать аргументы командной строки.
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:])
источник
argparse
вместоsys.argv
. Как бы это изменилось в этом случае? Кроме того, из внешнего скрипта я просто хочу передать несколько входных аргументов, которые вводит пользователь, в то время как другие входные аргументы для внутреннего скрипта (myModule.py) жестко запрограммированы мной.*
распаковывается массивf(a) => f([1,2,3])
противf(*a) => f(1,2,3)
вас может так же легко сделатьmyModule.main(sys.argv[1], "other value", 39)
или любой другой .