Argparse: “İsteğe bağlı bağımsız değişkenler” altında listelenen gerekli bağımsız değişkenler mi?


229

Bazı bağımsız değişkenleri ayrıştırmak için aşağıdaki basit kodu kullanın; bunlardan birinin gerekli olduğunu unutmayın. Ne yazık ki, kullanıcı argümanı sağlamadan komut dosyasını çalıştırdığında, görüntülenen kullanım / yardım metni çok kafa karıştırıcı bulduğum isteğe bağlı olmayan bir argüman olduğunu göstermez. Bir argümanın isteğe bağlı olmadığını belirtmek için python'u nasıl alabilirim?

İşte kod:

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Foo')
    parser.add_argument('-i','--input', help='Input file name', required=True)
    parser.add_argument('-o','--output', help='Output file name', default="stdout")
    args = parser.parse_args()
    print ("Input file: %s" % args.input )
    print ("Output file: %s" % args.output )

Gerekli bağımsız değişkeni sağlamadan kod üzerinde çalışırken, aşağıdaki çıktıyı alıyorum:

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

optional arguments:
    -h, --help            show this help message and exit
    -i INPUT, --input INPUT
                          Input file name
    -o OUTPUT, --output OUTPUT
                          Output file name

5
Kullanım hattında, -i INPUTparça, gerçekten gerekli olduğunu gösteren ince köşeli parantezlerle çevrili değildir. Ayrıca, bunu helpparam aracılığıyla manuel olarak açıklayabilirsiniz
Jaime RGP

7
@JaimeRGP Evet, ama bu elbette yeterli değil ve aynı zamanda önemli. optional argumentsGerekli bağımsız değişkenler için atanan grup adı hala yanıltıcı.
Acumenus

Yanıtlar:


316

-Veya --ile başlayan parametreler genellikle isteğe bağlıdır. Diğer tüm parametreler konumsal parametrelerdir ve tasarımın gerektirdiği şekilde (konumsal fonksiyon bağımsız değişkenleri gibi). İsteğe bağlı argümanlar talep etmek mümkündür, ancak bu biraz tasarımlarına aykırıdır. Halen konumsal olmayan argümanların bir parçası olduklarından, gerekirse bile kafa karıştırıcı “isteğe bağlı argümanlar” başlığı altında listeleneceklerdir. Bununla birlikte, kullanım bölümündeki eksik köşeli parantezler gerçekten gerekli olduklarını göstermektedir.

Ayrıca belgelere bakın :

Genel olarak, argparse modülü, -f ve --bar gibi bayrakların, komut satırında her zaman atlanabilecek isteğe bağlı bağımsız değişkenleri gösterdiğini varsayar.

Not: Gerekli seçenekler genellikle kötü form olarak kabul edilir, çünkü kullanıcılar seçeneklerin isteğe bağlı olmasını bekler ve bu nedenle mümkün olduğunca kaçınılmalıdır.

Bununla birlikte , yardımdaki “konumsal argümanlar” ve “isteğe bağlı argümanlar” başlıkları , argümanların otomatik olarak ayrıldığı iki argüman grubu tarafından oluşturulur. Şimdi, "bunu hackleyebilir" ve isteğe bağlı olanların adını değiştirebilirsiniz, ancak çok daha şık bir çözüm, "gerekli adlandırılmış argümanlar" (ya da onları çağırmak istediğiniz ne olursa olsun) için başka bir grup oluşturmak olacaktır:

parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT

Foo

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file name

required named arguments:
  -i INPUT, --input INPUT
                        Input file name

Aynı sorunu yaşıyorum. Size çözüm denedim. Yeni gruba bağımsız değişkenler ekler, ancak kodum bundan sonra çalışmıyor gibi görünüyor. Herhangi bir çözüm takdir edilecektir. Koduma
Zarar Mahmud

1
@ZararMahmud: Kodunuzun 24. satırında boş bağımsız değişkenler veriyorsunuz: parser.parse_args([])Bunun yerine, sys.argv parser.parse_args()içeriğini yakalamak için bağımsız değişken kullanmadan kullanın . Arpparse
Devin

@poke: Güzel çözüm! Ancak bu, karşılıklı münhasır gruplara ihtiyacınız olması durumunda işe yaramıyor, yoksa bir şey mi kaçırıyorum?
Yargıç


79

İsteğe bağlı önce gerekli bağımsız değişkenleri listelemeyi tercih ettiğim için, bu yolu kullanarak hack:

    parser = argparse.ArgumentParser()
    parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    required.add_argument('--required_arg', required=True)
    optional.add_argument('--optional_arg')
    return parser.parse_args()

ve bu çıktılar:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
               [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  --optional_arg OPTIONAL_ARG

İsteğe bağlı argümanlar grubunda 'yardım' göstermeden yaşayabilirim.


3
Bu aslında argparse'yi argümanlardan herhangi birini gerektiği gibi ele almaya zorlar mı?
Anthony

6
Bir argüman eklerken 'zorunlu' argümanın hala ayarlanması gerektiğini düşünüyorum.
Karl Rosaen

Bu gerçekten iyi.
Paul Cezanne

7
@Anthony - hayır bunun için add_argument içinde 'required = True' ya ihtiyacınız var. Yukarıdaki cevap sadece argüman gruplamasını göstermektedir.
user2275693

47

@Karl Rosaen bina inşaatı

parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() # Edited this line
required = parser.add_argument_group('required arguments')
# remove this line: optional = parser...
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
parser._action_groups.append(optional) # added this line
return parser.parse_args()

ve bu çıktılar:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  -h, --help                    show this help message and exit
  --optional_arg OPTIONAL_ARG

1
BTW, _action_groupkorunan üyeye erişmeden erişmenin herhangi bir yolu (yöntemi) var mı? Benim durumumda zaten var olan (özel) gruba bazı argümanlar eklemem gerekiyor.
makine

Bu harika. İkinci bir isteğe bağlı listede görünen --help öğesini çözer.
Jeremy

Not : Bu cevap, açıkta kalan API'yı kırar, aşağıda Bryan_D tarafından verilen yanıtı kontrol edin .
lol

18

@RalphyZ'den bir kez daha inerek

Bu, maruz kalan API'yı bozmaz.

from argparse import ArgumentParser, SUPPRESS
# Disable default help
parser = ArgumentParser(add_help=False)
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')

# Add back help 
optional.add_argument(
    '-h',
    '--help',
    action='help',
    default=SUPPRESS,
    help='show this help message and exit'
)
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')

Hangi yukarıdaki ile aynı gösterecektir ve gelecekteki sürümleri hayatta gerekir:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  -h, --help                    show this help message and exit
  --optional_arg OPTIONAL_ARG

RalphyZ'in cevabının maruz kalan API'yı nasıl bozduğunu açıklayabilir misiniz?
jeremysprofile

5
_action_groupsyalnızca dahili kullanım için tasarlanmıştır. Bu nedenle, sürümler arasında uyumluluk garantisi yoktur.
Bryan_D
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.