簡體   English   中英

在 Python 中,我可以調用導入模塊的 main() 嗎?

[英]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.pyparse_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM