[英]In Python, can I call the main() of an imported module?
在 Python 中,我有一個模塊myModule.py,我在其中定義了一些函數和一個main() ,它需要一些命令行參數。
我通常從 bash 腳本調用這個 main() 。 現在,我想把所有東西都放在一個小包里,所以我想也許我可以把我簡單的 bash 腳本變成一個 Python 腳本,然后把它放在包里。
那么,我實際上如何從MyFormerBashScript.py的 main() 函數調用myModule.py的 main() 函數? 我什至可以這樣做嗎? 我如何向它傳遞任何參數?
這只是一個函數。 導入並調用它:
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
代碼被視為一個模塊( import filename
),那么 python 將使用它作為模塊名稱。 在這兩種情況下,變量__name__
被設置了,針對它的測試會告訴你你的代碼是如何運行的。
Martijen 的回答是有道理的,但它遺漏了一些對其他人來說似乎很明顯但我很難弄清楚的重要內容。
在你使用 argparse 的版本中,你需要在主體中有這一行。
args = parser.parse_args(args)
通常,當您僅在腳本中使用 argparse 時,您只需編寫
args = parser.parse_args()
和 parse_args 從命令行查找參數。 但是在這種情況下,main 函數無法訪問命令行參數,因此您必須告訴 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
這取決於。 如果主代碼受if
保護,如下所示:
if __name__ == '__main__':
...main code...
那么不,你不能讓 Python 執行它,因為你不能影響自動變量__name__
。
但是當所有代碼都在一個函數中時,那么也許可以。 嘗試
import myModule
myModule.main()
即使模塊使用__all__
保護自己,這也有效。
from myModule import *
可能不會使main
對您可見,因此您確實需要導入模塊本身。
我也有使用argparse
的同樣需求。 問題是argparse.ArgumentParser
對象實例的parse_args
函數默認從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:])
關鍵點是將 args 傳遞給parse_args
函數。 稍后,要使用 main,您只需按照 Martijn 所說的去做。
我正在尋找的答案在這里得到了回答: How to use python argparse with args than 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()
並在另一個 python 腳本中使用parser.parse_args(['--input', 'foobar.txt'])
解析參數:
# 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:])
我遇到了這個問題,我無法調用文件Main()
方法,因為它用這些點擊選項裝飾,例如:
# @click.command()
# @click.option('--username', '-u', help="Username to use for authentication.")
當我刪除這些裝飾/屬性時,我可以從另一個文件成功調用 Main() 方法。
from PyFileNameInSameDirectory import main as task
task()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.