無效的過程呼叫或引數_python中關於傳遞引數模組argprase的一些小坑
技術標籤:無效的過程呼叫或引數
今天在寫程式碼的時候遇到了一個關於parser的一些小坑,記錄在此備用。
我們知道在python中可以用argprase來傳遞一些引數給程式碼執行,來看下面的例子,假設現在有一個test資料夾,下面有3個python檔案,分別用a.py;b.py;c.py來表示,目錄樹如下。
每一個的初始程式碼為一個簡單的print函式。
# a.py def out_a(): print("I am a.py") if __name__ == '__main__': out_a() # b.py def out_b(): print("I am b.py") if __name__ == '__main__': out_b() # c.py def out_c(): print("I am c.py") if __name__ == '__main__': out_c()
現在在a.py中引入模組argprase,並定義一些簡單的引數,程式碼如下:
# a.py import argparse parser = argparse.ArgumentParser() parser.add_argument('--first_parameter', default='first') parser.add_argument('--second_parameter', default='second') parser.add_argument('--third_flag', action='store_true') args = parser.parse_args() print(args) def out_a(): print("I am a.py") if __name__ == '__main__': out_a()
這裡面簡單說一下第3個引數,這也是我今天想記錄文章的原因,這個引數是argparse裡面提供的開關布林選項,actions記錄的是一個動作,意味著在呼叫這個函式的時候,如果在命令列新增這個引數,則該引數為True,如果不新增這個引數,則該引數為False,歸納起來為如下的兩個圖。
對於這種開關布林選項更為詳細的介紹,可以參考知乎問題:
Argparse中action的可選引數store_true,store_false到底是什麼意思?www.zhihu.com到目前為止沒有出現問題,接下來,我希望b.py也使用引數,並且還希望使用a.py裡面的函式,因此我對b.py進行如下修改。
from a import out_a
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--fourth_parameter', default='fourth')
parser.add_argument('--fifth_parameter', default='fifth')
parser.add_argument('--sixth_flag', action='store_true')
args = parser.parse_args()
def out_b():
print("I am b.py")
if __name__ == '__main__':
out_b()
out_a()
然後同樣的,我們分別用兩種方式來測試b.py,效果如下。
當時我看到這裡的時候想了很久,排除了拼寫錯誤的情況以後,觀察這裡面的輸出,發現看到的是a.py當中的3個引數,而不是b.py當中設定的引數,於是我將a.py和b.py的引數表打印出來,看到這樣子的結果。
可以發現儘管我使用的是from a import out_a,但依然引入了a.py當中的引數表,並且後引入的b.py的引數表沒有辦法覆蓋掉。下面在c.py中同樣引入3個引數,然後引入b.py的方法,程式碼如下:
from b import out_b
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--seventh_parameter', default='seventh')
parser.add_argument('--eighth_parameter', default='eighth')
parser.add_argument('--ninth_flag', action='store_true')
args = parser.parse_args()
print(args)
def out_c():
print("I am c.py")
if __name__ == '__main__':
out_c()
out_b()
效果如下
看到有3個引數列表輸出就知道c.py的引數也是無效的了,驗證一下。
解決方案:
其實只需要將所有的引數表放到同一個檔案裡面就可以了,比如utils.py,由於這裡是同一個資料夾下的3個檔案,在import呼叫的時候就只需要初始化一次所有引數就可以使用了,有點類似於C語言當中的全域性變數,因為這個東西排查了一個多小時,也是有點惱火了。
最後賣一下我的部落格......
JCChan - 部落格園www.cnblogs.com