TL; DR
Gunakan nargs
opsi atau 'append'
pengaturan action
opsi (tergantung bagaimana Anda ingin antarmuka pengguna berperilaku).
nargs
parser.add_argument('-l','--list', nargs='+', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 2345 3456 4567
nargs='+'
membutuhkan 1 atau lebih argumen, nargs='*'
membutuhkan nol atau lebih.
menambahkan
parser.add_argument('-l','--list', action='append', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 -l 2345 -l 3456 -l 4567
Dengan append
Anda memberikan opsi beberapa kali untuk membangun daftar.
Jangan gunakan type=list
!!! - Mungkin tidak ada situasi di mana Anda akan ingin menggunakan type=list
dengan argparse
. Pernah.
Mari kita lihat lebih detail beberapa cara berbeda yang bisa dilakukan seseorang untuk melakukan ini, dan hasil akhirnya.
import argparse
parser = argparse.ArgumentParser()
# By default it will fail with multiple arguments.
parser.add_argument('--default')
# Telling the type to be a list will also fail for multiple arguments,
# but give incorrect results for a single argument.
parser.add_argument('--list-type', type=list)
# This will allow you to provide multiple arguments, but you will get
# a list of lists which is not desired.
parser.add_argument('--list-type-nargs', type=list, nargs='+')
# This is the correct way to handle accepting multiple arguments.
# '+' == 1 or more.
# '*' == 0 or more.
# '?' == 0 or 1.
# An int is an explicit number of arguments to accept.
parser.add_argument('--nargs', nargs='+')
# To make the input integers
parser.add_argument('--nargs-int-type', nargs='+', type=int)
# An alternate way to accept multiple inputs, but you must
# provide the flag once per input. Of course, you can use
# type=int here if you want.
parser.add_argument('--append-action', action='append')
# To show the results of the given option to screen.
for _, value in parser.parse_args()._get_kwargs():
if value is not None:
print(value)
Inilah output yang bisa Anda harapkan:
$ python arg.py --default 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567
$ python arg.py --list-type 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567
$ # Quotes won't help here...
$ python arg.py --list-type "1234 2345 3456 4567"
['1', '2', '3', '4', ' ', '2', '3', '4', '5', ' ', '3', '4', '5', '6', ' ', '4', '5', '6', '7']
$ python arg.py --list-type-nargs 1234 2345 3456 4567
[['1', '2', '3', '4'], ['2', '3', '4', '5'], ['3', '4', '5', '6'], ['4', '5', '6', '7']]
$ python arg.py --nargs 1234 2345 3456 4567
['1234', '2345', '3456', '4567']
$ python arg.py --nargs-int-type 1234 2345 3456 4567
[1234, 2345, 3456, 4567]
$ # Negative numbers are handled perfectly fine out of the box.
$ python arg.py --nargs-int-type -1234 2345 -3456 4567
[-1234, 2345, -3456, 4567]
$ python arg.py --append-action 1234 --append-action 2345 --append-action 3456 --append-action 4567
['1234', '2345', '3456', '4567']
Takeaways :
- Gunakan
nargs
atauaction='append'
nargs
bisa lebih mudah dari perspektif pengguna, tetapi bisa tidak intuitif jika ada argumen posisi karena argparse
tidak bisa mengatakan apa yang seharusnya menjadi argumen posisi dan apa yang menjadi milik nargs
; jika Anda memiliki argumen posisi maka action='append'
mungkin berakhir menjadi pilihan yang lebih baik.
- Di atas hanya berlaku jika
nargs
diberikan '*'
, '+'
atau '?'
. Jika Anda memberikan angka integer (seperti 4
) maka tidak akan ada masalah dengan opsi campuran nargs
dan argumen posisi karena argparse
akan tahu persis berapa banyak nilai yang diharapkan untuk opsi tersebut.
- Jangan gunakan kutipan di baris perintah 1
- Jangan gunakan
type=list
, karena akan mengembalikan daftar daftar
- Ini terjadi karena di bawah tenda
argparse
menggunakan nilai type
untuk memaksa setiap individu memberikan argumen yang Anda pilih type
, bukan agregat dari semua argumen.
- Anda dapat menggunakan
type=int
(atau apa pun) untuk mendapatkan daftar int (atau apa pun)
1 : Maksud saya tidak secara umum .. Maksud saya menggunakan tanda kutip untuk memberikan daftarargparse
bukan yang Anda inginkan.
type=list
opsi ini. Jangan gunakan itu. Itu mengubah string menjadi daftar, dan karenanya daftar daftar.type
parameter ke beberapa objek lain. Secara default metode ini mengembalikan daftar string.--
dapat memecah opsi vs argumen posisi.prog --opt1 par1 ... -- posp1 posp2 ...
--
membantu untuk mencari tahu ini seperti yang ditunjukkan dalam contoh di komentar saya sebelumnya. Persediaan pengguna TKI--
diikuti oleh semua argumen posisi.Saya lebih suka melewatkan string yang dibatasi yang saya uraikan nanti dalam skrip. Alasan untuk ini adalah; daftar dapat dari jenis apa pun
int
ataustr
, dan kadang-kadang menggunakannargs
saya mengalami masalah jika ada beberapa argumen opsional dan argumen posisi.Kemudian,
atau,
akan bekerja dengan baik. Pembatas bisa berupa spasi juga, yang akan memberlakukan tanda kutip di sekitar nilai argumen seperti pada contoh dalam pertanyaan.
sumber
type
argumenlambda s: [int(time) for item in s.split(',')]
alih-alih pasca-pemrosesanargs.list
.int(time)
seharusnyaint(item)
. Contoh saya adalah versi sederhana dari apa yang biasanya saya lakukan, di mana saya memeriksa banyak hal lain daripada pemrosesan sederhana. Tapi untuk sekadar menjawab pertanyaan, saya juga menemukan cara Anda lebih elegan ..lambda items: list(csv.reader([items]))[0]
dengan pustaka csv standar adalah versi modifikasi dari komentar dari @chepner untuk siapa pun yang khawatir tentang input CSV sewenang-wenang (ref: answer from @adamk ).Selain itu
nargs
, Anda mungkin ingin menggunakanchoices
jika mengetahui daftar sebelumnya:sumber
Menggunakan parameter nargs dalam metode add_argument argparse
Saya menggunakan nargs = ' ' sebagai parameter add_argument. Saya secara khusus menggunakan nargs = ' ' ke opsi untuk memilih default jika saya tidak memberikan argumen eksplisit
Termasuk cuplikan kode sebagai contoh:
Contoh: temp_args1.py
Harap Dicatat: Kode contoh di bawah ini ditulis dalam python3. Dengan mengubah format pernyataan cetak, dapat berjalan di python2
Catatan: Saya mengumpulkan beberapa argumen string yang disimpan dalam daftar - opts.alist Jika Anda ingin daftar bilangan bulat, ubah parameter tipe pada parser.add_argument menjadi int
Hasil Eksekusi:
sumber
temp_args1.py -i [item5 ,item6, item7]
dan minta outputnya keluar sebagai daftar juga (bukan daftar bersarang)Jika Anda bermaksud membuat satu sakelar, ambil beberapa parameter, lalu gunakan
nargs='+'
. Jika contoh Anda '-l' sebenarnya mengambil bilangan bulat:Menghasilkan
Jika Anda menentukan argumen yang sama beberapa kali, tindakan default (
'store'
) menggantikan data yang ada.Alternatifnya adalah menggunakan
append
tindakan:Yang menghasilkan
Atau Anda bisa menulis custom handler / action untuk mengurai nilai yang dipisahkan koma sehingga Anda bisa melakukannya
sumber
In
add_argument()
,type
hanyalah objek yang bisa dipanggil yang menerima string dan mengembalikan nilai opsi.Ini akan memungkinkan untuk:
sumber
Jika Anda memiliki daftar bersarang di mana daftar bagian dalam memiliki tipe dan panjang yang berbeda dan Anda ingin mempertahankan tipe tersebut, misalnya,
[[1, 2], ["foo", "bar"], [3.14, "baz", 20]]
maka Anda dapat menggunakan solusi yang diusulkan oleh @ sam-mason untuk pertanyaan ini , yang ditunjukkan di bawah ini:
pemberian yang mana:
sumber
Saya ingin menangani melewati beberapa daftar, nilai integer, dan string.
Tautan Bermanfaat => Bagaimana cara mengirim variabel Bash ke Python?
Ketertiban tidak penting. Jika Anda ingin meneruskan daftar, lakukan seperti di antara
"["
dan"]
dan pisahkan menggunakan koma.Kemudian,
Output =>
['my_string', '3', ['1', '2'], ['3', '4', '5']]
,my_args
variabel berisi argumen secara berurutan.sumber
Saya pikir solusi paling elegan adalah dengan melewati fungsi lambda untuk "mengetik", seperti yang disebutkan oleh Chepner. Selain itu, jika Anda tidak tahu sebelumnya apa pembatas daftar Anda akan menjadi, Anda juga dapat melewati beberapa pembatas untuk re.split:
sumber
-l
dalam contoh panggilan? Dari mana-n
datangnya?parser.add_argument('-l', '--list', type = lambda s: re.split('[ ,;]', s))
. Berikut adalah input:script.py -l abc xyz, abc\nxyz
. Akhirnya, inilah hasilnya:script.py: error: unrecognized arguments: xyz, abcnxyz