2016-06-29 70 views
2

如何使用argparse和變量nargs做條件循環?所以,基本上,它應該運行或不運行。 我想:argparse中的可選nargs變量

parser = argparse.ArgumentParser(description="output parser") 
group = parser.add_mutually_exclusive_group() 
group.add_argument("--dos", help="get DOSCAR for plot", 
        nargs="?", metavar=("int")) 
args = parser.parse_args() 

if args.dos:  
    if len(args.dos) > 1: 
     chosen = int(args.dos[0]) 
     chdos = "at_dos"+args.dos[0]+".dat" 
    else: 
     chosen = None 

    inpt = "DOSY" 
    print(chosen) 
    print(inpt) 

現在,如果我有變量,那麼它的打印一些值,錯誤的,但一些價值:

$python3 vasp.py --dos 111 
111 
None # IT SHOULDN'T BE NONE 
DOSY 

但沒有不用爭論。

我也試圖與正常sys.argv中,如:

def get_dos(): 
    if len(sys.argv) > 2: 
     chosen = int(sys.argv[2]) 
     chdos = "at_dos"+sys.argv[2]+".dat" 
    else: 
     chosen = None 
    inpt = "DOSCAR" 
    print(sys.argv) 

    print(args.dos) 
    print(chosen) 
    print(inpt) 
在這種情況下

,當選項,它給出正確的結果:

python3 vasp.py --dos 12 
['vasp.py', '--dos', '12'] 
12 
12 
DOSCAR 

但同樣,沒有什麼選項:

$python3 vasp.py --dos 

我試過hpaulj的建議。它給出:

$python3 tt.py --dos 12 
Namespace(dos='12') 
1 
DOSY 

並且沒有參數,它仍然不打印任何東西。

+0

我沒有得到'None'當我運行它,並修復無效的語法。你使用的是什麼版本的Python?我已經嘗試了3.5.1和2.7.11,並且它在兩個版本中都可以使用。你需要一個[mcve]。 –

+1

另外,我不認爲'len(args.dos)> 1'會做你認爲它的作用。它會檢查您是否輸入了超過1位數字的號碼。 –

+2

您是否嘗試過'print(args)'來直接查看被解析​​的內容? – hpaulj

回答

0

感謝給所有回覆的人,特別是@hpaulj。但他們都沒有真正解決我的問題。所以,我採取了其他的方式。我在這裏發佈這個完整性。

#!/usr/bin/python3 
import argparse 

parser = argparse.ArgumentParser(description="output parser") 
group = parser.add_mutually_exclusive_group() 
group.add_argument("--dos", help="get DOSCAR for plot",action='store_true') 
parser.add_argument("-n", help="Showing last n line", 
        metavar='integer', type=int) 

args = parser.parse_args() 
if args.dos: 
    if args.n: 
     chosen = int(args.n) 
     chdos = "at_dos"+str(args.n)+".dat" 
    else: 
     chosen = None 
    inpt = "DOSY" 
    print(inpt) 
    print(chosen) 

其正常產生預期的結果:

$python3 tt.py --dos 
DOSY 
None 

$python3 tt.py --dos -n 222 
DOSY 
222 
0

您需要替換nargs =「?」與nargs =「*」。將nargs設置爲「?」意味着會有1個可選參數。你想要的是一個可選參數列表,即「*」。像這樣。

import argparse 
parser = argparse.ArgumentParser(description="output parser") 
group = parser.add_mutually_exclusive_group() 
group.add_argument("--dos", help="get DOSCAR for plot", 
       nargs="*", metavar=("int")) 
args = parser.parse_args() 

if args.dos:  
    if len(args.dos) > 1: 
     chosen = int(args.dos[0]) 
     chdos = "at_dos"+args.dos[0]+".dat" 
    else: 
     chosen = None 

    inpt = "DOSY" 
    print(chosen) 
    print(inpt) 
+0

我已經嘗試過nargs =「*」。你有沒有檢查過代碼?它給出同樣的問題。 – BaRud

3

簡化您的解析器,IPython的會話:

In [1004]: parser=argparse.ArgumentParser()  
In [1005]: parser.add_argument('--dos', nargs='?') 

In [1007]: parser.parse_args('--dos 111'.split()) 
Out[1007]: Namespace(dos='111') 

在這種情況下args.dos將字符串「111」,與len 3,和int(args.dos[0])數字1同樣發生在你離開nargs空白(默認無)。

nargs='?'我也可以使用沒有參數的標誌,在這種情況下,該值是默認的None

In [1013]: parser.parse_args('--dos'.split()) 
Out[1013]: Namespace(dos=None) 

nargs=is most useful with a const , which gives a convenient 3 way action. I can add type = int`將字符串(如果有的話)轉換爲整數。

In [1015]: parser.add_argument('--dos', nargs='?', type=int, 
    default=None, const=123) 

In [1016]: parser.parse_args([]) # not used 
Out[1016]: Namespace(dos=None) 

In [1017]: parser.parse_args('--dos'.split()) # without argument 
Out[1017]: Namespace(dos=123) 

In [1018]: parser.parse_args('--dos 456'.split()) # with argument 
Out[1018]: Namespace(dos=456) 

其他nargs,像1, '*' 和 '+' 給你一個列表,你可以檢查長度等

============= =======

在你argv測試

if len(sys.argv) > 2: 
    chosen = int(sys.argv[2]) 
    chdos = "at_dos"+sys.argv[2]+".dat" 

sys.argv是一個列表,因此,如果有足夠的元素應用sys.argv[2]步驟LEN計數。

這不起作用,因爲args.dos是單個字符串,而不是列表。

if len(args.dos) > 1: 
    chosen = int(args.dos[0]) 
    chdos = "at_dos"+args.dos[0]+".dat" 

len(args.dos)然後在字符串中的字符數,和args.dos[0]是第一個字符。

============

如果我定義:

def get_dos(argv=None): 
    parser=argparse.ArgumentParser() 
    parser.add_argument('--dos', type=int, nargs='?') 
    args = parser.parse_args(argv) 
    chosen = args.dos 
    if chosen is not None: 
     chdos = 'at_dos%s.dat'%chosen 
    else: 
     chdos = '' 
    return chosen, chdos 

這些測試中產生,我認爲符合您的需求值:

In [1042]: get_dos([]) 
Out[1042]: (None, '') 

In [1043]: get_dos(['--dos']) 
Out[1043]: (None, '') 

In [1044]: get_dos(['--dos','123']) 
Out[1044]: (123, 'at_dos123.dat') 
+0

嗨, 感謝您的回覆。雖然這是行得通的,但我正在努力使解析器部分脫離def(--dos可能是其他選項)。 Byt謝謝 – BaRud