Jawaban:
Pada akhirnya, perbedaan antara try, exceptdan pengujian len(sys.argv)tidak terlalu signifikan. Keduanya agak sedikit hackish dibandingkan argparse.
Ini terjadi pada saya, meskipun - sebagai semacam argumen anggaran rendah:
arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))
Anda bahkan dapat menggunakannya untuk menghasilkan namedtupledengan nilai yang default None- semuanya dalam empat baris!
Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))
Jika Anda tidak terbiasa namedtuple, itu hanya tupel yang bertindak seperti objek, memungkinkan Anda mengakses nilainya menggunakan tup.attributesintaks alih-alih tup[0]sintaks.
Jadi baris pertama membuat namedtupletipe baru dengan nilai untuk setiap nilai dalam arg_names. Baris kedua meneruskan nilai dari argskamus, menggunakan getuntuk mengembalikan nilai default saat nama argumen yang diberikan tidak memiliki nilai terkait di kamus.
Periksa panjang sys.argv:
if len(sys.argv) > 1:
blah = sys.argv[1]
else:
blah = 'blah'
Beberapa orang lebih suka pendekatan berbasis pengecualian yang Anda sarankan (misalnya, try: blah = sys.argv[1]; except IndexError: blah = 'blah'), tetapi saya tidak terlalu menyukainya karena tidak “menskalakan” sebaik yang Anda inginkan (misalnya, ketika Anda ingin menerima dua atau tiga argumen) dan berpotensi menyembunyikan kesalahan (misalnya, jika Anda menggunakan blah = foo(sys.argv[1]), tetapi foo(...)memunculkan IndexError, itu IndexErrorakan diabaikan).
try, except. Tunggu saja fooargumen Anda sampai elseklausulnya.
argparse.
argparse.pysemua proyek baris perintah saya.
tryklausa… Jadi, mengingat itu tidak lebih sulit (dan, IMO, sedikit lebih cantik), saya lebih suka memeriksa panjangnya (juga, Anda menghindari orang berteriak pada Anda karena menggunakan pengecualian untuk kontrol aliran).
tryapologis, harus saya akui. Saya hanya merasa terkadang hal itu mengungkapkan maksud saya dengan lebih jelas daripada ifpernyataan.
Cara lain yang belum saya lihat adalah dengan mengatur nilai sentinel Anda sebelumnya. Metode ini memanfaatkan evaluasi malas Python, di mana Anda tidak selalu harus memberikan elsepernyataan. Contoh:
startingpoint = 'blah'
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
Atau jika Anda menggunakan sintaks CRAZY, Anda dapat menggunakan operator terner Python :
startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'
Saya menggunakan ini - tidak pernah gagal:
startingpoint = 'blah'
if sys.argv[1:]:
startingpoint = sys.argv[1]
startingpointvariabel dari contoh, tetapi pertanyaannya adalah menetapkan variabel mundur, jadi saya hanya membuat hal yang sama.
sys.argv[1:]:. Ini bekerja dengan argumen posisi sementara hitungan tidak.
Ini daftar Python biasa. Pengecualian yang Anda tangkap untuk ini adalah IndexError, tetapi Anda lebih baik memeriksa panjangnya saja.
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
else:
startingpoint = 'blah'
Sebuah solusi yang bekerja dengan fonction built-in map!
arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}
Maka Anda hanya perlu memanggil parameter Anda seperti ini:
if args['operation'] == "division":
if not args['parameter']:
...
if args['parameter'] == "euclidian":
...
Anda cukup menambahkan nilai argv [1] ke argv dan kemudian memeriksa apakah argv [1] tidak sama dengan string yang Anda masukkan. Contoh:
from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
print(argv[1])
Cukup dekat dengan apa yang coba dilakukan oleh pencetusnya. Berikut adalah fungsi yang saya gunakan:
def get_arg(index):
try:
sys.argv[index]
except IndexError:
return ''
else:
return sys.argv[index]
Jadi penggunaannya akan seperti ini:
if __name__ == "__main__":
banner(get_arg(1),get_arg(2))