2012-06-30 22 views
5

Konumsal argümanları, ortaya çıktıklarında varolan "argüman durumu" ile ilişkilendirmek istiyorum. Örneğin, aşağıdaki komut satırı:Argüman konum argümanlarını argümanlarla argparse edebilir mi?

foo: m=1, r=0 (default value for r) 
bar: m=1, r=2 
baz: m=1, r=7 
quux: m=6, r=7 

bu argparse modülü ile yapılabilir:

script.py -m 1 foo -r 2 bar -r 7 baz -m 6 quux 

aşağıdaki dernek üretmek gerekir mi?

+0

"Bağımsız değişken durumları" kümesi sabit midir? Örneğin. Eğer sadece '(' foo ',' bar ',' baz ',' quux '...) hiç kullanılmayacaksa, ön tarafını biliyor musunuz? Ya da kullanıcı istedikleri yere istedikleri şeyi koyabilir mi? – mgilson

+0

@mgnilson - İstedikleri her şeyde; Baktığım şey dosya adları ve işlem seçeneklerinin listesi. Argparse'ın konumsal argümanların ele alınmasına dayanarak, bunun şu anda oynamış olduğum model olan özel bir Eylem olmadan gerçekleştirilemeyeceğini düşünüyorum. –

+0

Özel eylemleri de düşünüyordum, ama bu çok zor çünkü argparse tüm konumsal argümanların birlikte verildiğini varsayıyor gibi görünüyor. Tek çaremiz 'nargs = '*'' her yerde kullanmaktır ve daha sonra tüm eylemlerinizin içinde doğru numaraya sahip olduğunuzdan emin olmak için kontrol edin. (Bu en iyi kırılgan görünüyor). Tabii ki, izin verirseniz bu çok daha kolay olur: -m 1 -f foo -r 2 -f bar -r 7 -f baz -m 6 -f quux' – mgilson

cevap

1

Bu sizin için yararlı olmayabilir, ancak sys.argv'u parçalara ayırabiliyorsanız bu sorun daha kolay görünüyor - Esasen, hangi konumların "konumsal" argümanlar olduğu varsayılmalı. “Aslında konumsal olarak değil, dediğiniz gibi, herhangi bir yerde olabilirler” ve hangi parçaların bir çeşit argüman olması gerekiyordu. Aşağıdaki örnekte, örneğinizle çalışmak üzere ayarlamıştım, ancak dosyalarda veya belirli türde bir dosyada sys.argv'u kolayca bölebilirsiniz. condition işlevi yazmanız size kalmış. Gerisi (umarım) kendini açıklayıcı olacaktır.

import argparse 
import sys 
import copy 
import os 

def split_list(lst,condition): 
    current=[] 
    out=[current] 
    for arg in lst: 
     current.append(arg) 
     if(condition(arg)): 
      current=[] 
      out.append(current) 

    return out 


parser=argparse.ArgumentParser() 
parser.add_argument('-m',action='store') 
parser.add_argument('-r',default='0',action='store') 
#pieces=split_list(sys.argv[1:],os.path.isfile) 
pieces=split_list(sys.argv[1:],lambda x: x in ('foo','bar','baz','quux')) 
options={} #use collections.OrderedDict if order matters -- or some more suitable data structure. 
default=argparse.Namespace() 
for args in pieces: 
    if(not args): 
     continue 
    ns=copy.deepcopy(default) 
    default=parser.parse_args(args[:-1],namespace=ns) 
    options[args[-1]]=default 

print (options) 
+0

İlginç bir fikir! Lambda'yı 'x [0]! =" - "' olarak değiştirmek, yayınları etkin bir şekilde bölmek için çalışmalıdır (bence temel sözdizimi, -sadece ile başlayan dosya isimlerini kabul etmeyi mantıksız kılar). Bu konuda oynamama izin ver. –

+0

@BenBlank lambda'yı '' x.startswith ('-') 'olarak değiştirmem de ilk düşüncemdi, fakat '1' ile başlamıyor çünkü test örneğinde başarısız oluyor '- – mgilson

+0

adlandırılmış bir parametreden sonra bölünmeyi reddeden sabit kodlu mantıkla birlikte lambda] (https://gist.github.com/3026853). Bu değişiklikle, tam olarak ihtiyacım olan şeyi yapıyor! Yardım için teşekkürler. –

İlgili konular