Komut dosyası için bir değişkenin aktarılıp aktarılmadığını kontrol etmenin en iyi yolu nedir?
try:
sys.argv[1]
except NameError:
startingpoint = 'blah'
else:
startingpoint = sys.argv[1]
Yanıtlar:
Sonuç olarak, try, exceptve test arasındaki fark len(sys.argv)o kadar da önemli değil. İkisi de biraz hilekar argparse.
Yine de bu benim aklıma geliyor - bir tür düşük bütçeli argüman olarak:
arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))
namedtupleVarsayılan değerlere sahip bir oluşturmak için bile kullanabilirsiniz None- hepsi dört satırda!
Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))
Aşina değilseniz namedtuple, bu sadece bir nesne gibi davranan ve değerlerine tup.attributesözdizimi yerine tup[0]sözdizimi kullanarak erişmenize izin veren bir demettir .
Dolayısıyla, ilk satır namedtuple, içindeki değerlerin her biri için değerler içeren yeni bir tür oluşturur arg_names. İkinci satır , verilen bağımsız değişken adı sözlükte ilişkili bir değere sahip olmadığında varsayılan bir değer döndürmek için argskullanarak sözlükten değerleri getiletir.
Uzunluğunu kontrol edin sys.argv:
if len(sys.argv) > 1:
blah = sys.argv[1]
else:
blah = 'blah'
Bazı insanlar önerdiğiniz istisna temelli yaklaşımı tercih ederler (örneğin try: blah = sys.argv[1]; except IndexError: blah = 'blah'), ancak bu kadar hoşuma gitmiyor çünkü bu kadar hoş bir şekilde "ölçeklenmiyor" (örneğin, iki veya üç argümanı kabul etmek istediğinizde) ve potansiyel olarak (eğer kullanılırsa, örneğin hataları gizleyebilir blah = foo(sys.argv[1]), ancak foo(...)bir kaldırdı IndexErrorki IndexErrorgöz ardı olurdu).
try, except. fooMaddeye kadar argümanınızı bekleyin else.
argparse.
argparse.pyTüm komut satırı projelerime girdim .
trymaddeye koyuyor ... Bu yüzden, daha zor olmadığı (ve IMO, biraz daha güzel) göz önüne alındığında, sadece uzunluğu kontrol etmeyi tercih ederim (ayrıca, akış kontrolü için istisnalar kullandığınız için size bağırırsınız).
tryözür diliyorum, itiraf etmeliyim. Bazen niyetimi bir ififadeden daha açık bir şekilde ifade ettiğini hissediyorum .
Henüz listelendiğini görmediğim bir başka yol da, koruyucu değerinizi vaktinden önce ayarlamaktır. Bu yöntem, her zaman bir elseifade sunmak zorunda olmadığınız Python'un tembel değerlendirmesinden yararlanır . Misal:
startingpoint = 'blah'
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
Veya CRAZY sözdizimine gidiyorsanız, Python'un üçlü operatörünü kullanabilirsiniz :
startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'
Bunu kullanıyorum - asla başarısız olmaz:
startingpoint = 'blah'
if sys.argv[1:]:
startingpoint = sys.argv[1]
startingpointDeğişkeni örnekten kaldırabilirim , ancak soru bir geri dönüş değişkeni atamak, bu yüzden ben de aynısını yaptım.
sys.argv[1:]:. Bu konumsal argümanlarla çalışır, count çalışmaz.
Sıradan bir Python listesi. Bunun için yakalayacağınız istisna IndexError'dır, ancak bunun yerine uzunluğu kontrol etmeniz daha iyidir.
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
else:
startingpoint = 'blah'
Yerleşik harita işleviyle çalışan bir çözüm!
arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}
O zaman parametrelerinizi şu şekilde çağırmalısınız:
if args['operation'] == "division":
if not args['parameter']:
...
if args['parameter'] == "euclidian":
...
Argv [1] değerini argv'ye ekleyebilir ve ardından argv [1] 'in girdiğiniz dizgeye eşit olup olmadığını kontrol edebilirsiniz Örnek:
from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
print(argv[1])