![](/img/trans.png)
[英]check unittest.mock call arguments agnostically w.r.t. whether they have been passed as positional arguments or keyword arguments
[英]Argparse: Check if any arguments have been passed
當沒有給出參數時,我的腳本應該啟動演示模式。 我試過這個:
args = parser.parse_args()
if len(args) == 0:
run_demo()
else:
# evaluate args
這給出了*** TypeError: object of type 'Namespace' has no len()
as args
is no list。
我將如何實現我想要的?
如果您的目標是檢測何時沒有給命令提供任何參數,那么通過argparse
執行此操作是錯誤的方法(正如 Ben 很好地指出的那樣)。
想簡單! :-) 我相信 argparse 不會減少sys.argv
。 因此, if not len(sys.argv) > 1
,則用戶未提供任何參數。
argparse 允許您根據您的規范和正在解析的命令行設置(在 Namespace 對象內)您添加到解析器的參數中提到的所有變量。 如果您設置了默認值,那么如果在命令行上沒有看到這些變量,它們將具有該默認值,它們不會出現在 Namespace 對象中。 如果您不指定默認值,則有一個隱式默認值None
。 因此,檢查 Namespace 對象的長度,無論您設法做什么,作為檢查是否解析任何參數的方法都沒有意義; 它應該始終具有相同的長度。
相反,如果你知道你有一堆沒有默認值的參數,並且你想檢查它們中的任何一個是否被設置為任何非None
值......這樣做。 您可以使用列表理解和vars
函數來循環它們,而不必復制來自add_argument
調用的名稱列表,如 Martijn 的回答所示。
如果您的某些參數具有默認值,則會變得有點棘手,如果它們具有可以在命令行上顯式提供的默認值(例如,默認為 0 的數字參數使得無法從用戶那里得知默認值)提供 0)。 在那種情況下,我不確定是否有一個通用的解決方案,在不知道參數是什么的情況下總是有效。
如果確實需要參數編號(無論出於何種原因)。 我發現這段代碼非常有幫助(但不知道它優化了多少,我很感激對它的任何評論)。
args = parser.parse_args()
print( len( vars(args) ) )
此版本僅計算 -xx 參數,而不計算傳遞的任何其他值。
如果你想要一切(還有傳遞的值),那么只需使用前面提到的len(sys.argv)
。
不要使用 argparse。 而是使用sys.argv
。 argparse
創建一個命名空間,因此它總是會為您提供一個帶有它們的值的“字典”,具體取決於您在調用腳本時使用的參數。
這是我過去所做的:
args = parser.parse_args()
if len(sys.argv) == 1:
parser.print_help()
sys.exit()
return args
我知道這是一個舊線程,但我找到了一個更直接的解決方案,可能對其他人也有用:
您可以檢查是否已傳遞任何參數:
if any(vars(args).values()):
# evaluate args
或者,如果沒有傳遞參數(注意not
運算符):
if not any(vars(args).values()):
run_demo()
解釋:
parse_args()
返回一個包含每個參數名稱及其關聯值的“命名空間”對象。 示例: Namespace(arg1='myfile.txt', arg2='some/path/to/some/folder')
如果沒有傳遞參數, parse_args()
將返回相同的對象,但所有值都為None
。 示例: Namespace(arg1=None, arg2=None)
但是,此對象不可迭代,因此您必須使用vars()
將其轉換為dict
以便我們可以訪問這些值。
最后,因為我們現在手頭有一個dict
,我們可以使用.values()
獲取所有值(在list
.values()
,並使用內置的any()
函數來檢查是否有任何值不是None
。 為了更清楚:如果在您提供給它的列表中沒有一個值不是None
、 False
或0
(檢查文檔以供參考), any()
將返回False
。
希望能幫助到你。
讓我們假設以下示例來擴展您的完整性:
#!/usr/bin/env python3
import argparse
...
def main():
parser = argparse.ArgumentParser()
parser.add_argument('input', nargs='?' action='store')
parser.add_argument('-l', '--length', type=int, action='store')
parser.add_argument('-v', '--verbose', action='store_true')
args = parser.parse_args()
if (args.input == None and args.length == None):
parser.print_help()
else:
print(args)
if __name__ == '__main__':
main()
@Ben 提到的 Namespace 對象在本例中是args
。 從parser.add_argument
的字符串創建一個變量。 您可以通過args.input
或args.length
或args.verbose
訪問它。 您可以通過執行print(args)
來驗證這一點,它實際上會顯示如下內容:
Namespace(input=None, length=None, verbose=False)
由於 verbose 設置為True
,如果存在,輸入和長度只是變量,不必實例化(不提供參數)。
如果您想確保不能同時提供兩個屬性,也可以使用group = parser.add_mutually_exclusive_group()
。
如需進一步參考,請參閱:
我擴展了 2dvisio 的概念來計算非零或無參數:
vm_opts = parser.parse_args()
v = vars(vm_opts)
n_args = sum([ 1 for a in v.values( ) if a])
對於最簡單的情況,您要檢查是否傳遞了所有輸入中相同的單一類型的參數,您可以使用argparse
和numpy
分三步完成。
import argparse
import numpy as np
args = parser.parse_args()
# namespace to dictionary
args_dict = vars(args)
# unpack values from dictionary, pass to array
values = np.array([*args_dict.values()])
# Check if the defaults have changed
args_indices = np.where(values != default)[0]
# Did we pass any arguments?
if len(values) == len(args_indices):
print("No arguments were passed")
長度用作代理來檢查是否已傳遞任何或沒有參數。 如果您想知道通過了哪一個,您可以打開密鑰並檢查更改后的索引。
np.array()
接受用於更復雜情況的邏輯運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.