python中關於傳遞參數模塊argprase的一些小坑


今天在寫代碼的時候遇到了一個關於parser的一些小坑,記錄在此備用。

我們知道在python中可以用argprase來傳遞一些參數給代碼執行,來看下面的例子,假設現在有一個test文件夾,下面有3個python文件,分別用a.py;b.py;c.py來表示,目錄樹如下。

 每一個的初始代碼為一個簡單的print函數。

1 #a.py
2 def out_a():
3     print("I am a.py")
4 
5 
6 if __name__ == '__main__':
7     out_a()
1 #b.py
2 def out_b():
3     print("I am b.py")
4 
5 
6 if __name__ == '__main__':
7     out_b()
1 #c.py
2 def out_c():
3     print("I am c.py")
4 
5 
6 if __name__ == '__main__':
7     out_c()

現在在a.py中引入模塊argprase,並定義一些簡單的參數,代碼如下

 1 import argparse
 2 parser = argparse.ArgumentParser()
 3 parser.add_argument('--first_parameter', default='first')
 4 parser.add_argument('--second_parameter', default='second')
 5 parser.add_argument('--third_flag', action='store_true')
 6 args = parser.parse_args()
 7 
 8 
 9 def out_a():
10     print("I am a.py")
11 
12 
13 if __name__ == '__main__':
14     out_a()

這里面簡單說一下第3個參數,這也是我今天想記錄文章的原因,這個參數是argparse里面提供的開關布爾選項,actions記錄的是一個動作,意味着在調用這個函數的時候,如果在命令行添加這個參數,則該參數為True,如果不添加這個參數,則該參數為False,歸納起來為如下的兩個圖。

這個是沒有指定第3個參數的情況

 

這個是指定第3個參數的情況

對於這種開關布爾選項更為詳細的介紹,可以參考知乎問題:Argparse中action的可選參數store_true,store_false到底是什么意思?

到目前為止沒有出現問題,接下來,我希望b.py也使用參數,並且還希望使用a.py里面的函數,因此我對b.py進行如下修改。

 1 from a import out_a
 2 import argparse
 3 parser = argparse.ArgumentParser()
 4 parser.add_argument('--fourth_parameter', default='fourth')
 5 parser.add_argument('--fifth_parameter', default='fifth')
 6 parser.add_argument('--sixth_flag', action='store_true')
 7 args = parser.parse_args()
 8 
 9 
10 def out_b():
11     print("I am b.py")
12 
13 
14 if __name__ == '__main__':
15     out_b()
16     out_a()

然后同樣的,我們分別用兩種方式來測試b.py,效果如下。

這個是不使用參數的情況 

這個是使用參數的情況

可以看到報錯了,當時我看到這里的時候想了很久,排除了拼寫錯誤的情況以后,觀察這里面的輸出,發現看到的是a.py當中的3個參數,而不是b.py當中設置的參數,於是我將a.py和b.py的參數表打印出來,看到這樣子的結果。

輸出兩個python文件的參數表

可以發現盡管我使用的是 from a import out_a ,但依然引入了a.py當中的參數表,並且后引入的b.py的參數表沒有辦法覆蓋掉。下面在c.py中同樣引入3個參數,然后引入b.py的方法,代碼如下:

 1 from b import out_b
 2 import argparse
 3 parser = argparse.ArgumentParser()
 4 parser.add_argument('--seventh_parameter', default='seventh')
 5 parser.add_argument('--eighth_parameter', default='eighth')
 6 parser.add_argument('--ninth_flag', action='store_true')
 7 args = parser.parse_args()
 8 print(args)
 9 
10 def out_c():
11     print("I am c.py")
12 
13 
14 if __name__ == '__main__':
15     out_c()
16     out_b()

效果如下

不使用任何參數調用c.py

看到有3個參數列表輸出就知道c.py的參數也是無效的了,驗證一下。

使用參數調用c.py

 

解決方案:

其實只需要將所有的參數表放到同一個文件里面就可以了,比如utils.py,由於這里是同一個文件夾下的3個文件,在import調用的時候就只需要初始化一次所有參數就可以使用了,有點類似於C語言當中的全局變量,因為這個東西排查了一個下午,也是有點惱火了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM