Diberi fungsi Python:
def a_method(arg1, arg2):
pass
Bagaimana saya bisa mengekstrak jumlah dan nama argumen. Yaitu, mengingat bahwa saya memiliki referensi func
, saya ingin func.[something]
kembali ("arg1", "arg2")
.
Skenario penggunaan untuk ini adalah bahwa saya memiliki dekorator, dan saya ingin menggunakan argumen metode dalam urutan yang sama dengan yang muncul untuk fungsi aktual sebagai kunci. Yaitu, bagaimana dekorator akan terlihat dicetak "a,b"
saat saya menelepon a_method("a", "b")
?
Jawaban:
Lihatlah
inspect
modul - ini akan melakukan pemeriksaan berbagai properti objek kode untuk Anda.Hasil lainnya adalah nama variabel * args dan ** kwargs, dan default yang disediakan. yaitu.
Perhatikan bahwa beberapa callable mungkin tidak dapat ditinjau dalam implementasi Python tertentu. Misalnya, dalam CPython, beberapa fungsi bawaan yang didefinisikan dalam C tidak memberikan metadata tentang argumennya. Akibatnya, Anda akan mendapatkan
ValueError
jika Anda menggunakaninspect.getfullargspec()
fungsi bawaan.Karena Python 3.3, Anda dapat menggunakan
inspect.signature()
untuk melihat tanda tangan panggilan dari objek yang bisa dipanggil:sumber
(4,)
sesuai dengan parameter kata kuncic
secara khusus?inspect.getargspec
sudah usang , tetapi penggantinyainspect.getfullargspec
.Dalam CPython, jumlah argumen adalah
dan nama mereka ada di awal
Ini adalah detail implementasi CPython, jadi ini mungkin tidak berfungsi dalam implementasi Python lainnya, seperti IronPython dan Jython.
Salah satu cara portabel untuk mengakui argumen "pass-through" adalah dengan mendefinisikan fungsi Anda dengan tanda tangan
func(*args, **kwargs)
. Ini banyak digunakan di misalnya matplotlib , di mana lapisan API luar melewati banyak argumen kata kunci ke API tingkat rendah.sumber
*args
, misalnya:def foo(x, *args, y, **kwargs): # foo.__code__.co_argcount == 1
Dalam metode dekorator, Anda dapat membuat daftar argumen dari metode asli dengan cara ini:
Jika
**kwargs
yang penting bagi Anda, maka itu akan sedikit rumit:Contoh:
sumber
Saya pikir yang Anda cari adalah metode lokal -
sumber
Versi Python 3 adalah:
Metode mengembalikan kamus yang berisi args dan kwargs.
sumber
[:fn.__code__.co_argcount]
ini sangat penting jika Anda mencari argumen fungsi - jika tidak, ia juga menyertakan nama yang dibuat di dalam fungsi.Ini adalah sesuatu yang saya pikir akan bekerja untuk apa yang Anda inginkan, menggunakan dekorator.
Jalankan, itu akan menghasilkan output berikut:
sumber
Python 3.5+:
Jadi sebelumnya:
Sekarang:
Untuk menguji:
Mengingat bahwa kita memiliki fungsi 'fungsi' yang mengambil argumen 'argumen', ini akan mengevaluasi sebagai Benar, sebaliknya sebagai Salah.
Contoh dari konsol Python:
sumber
Dalam Python 3. + dengan
Signature
objek yang ada di tangan, cara mudah untuk mendapatkan pemetaan antara nama argumen dengan nilai, menggunakan metode Signaturebind()
!Sebagai contoh, berikut adalah dekorator untuk mencetak peta seperti itu:
sumber
Berikut ini cara lain untuk mendapatkan parameter fungsi tanpa menggunakan modul apa pun.
Keluaran:
sumber
Mengembalikan daftar nama argumen, menangani sebagian dan fungsi reguler:
sumber
Pembaruan untuk jawaban Brian :
Jika fungsi di Python 3 memiliki argumen hanya kata kunci, maka Anda perlu menggunakan
inspect.getfullargspec
:menghasilkan ini:
sumber
Dalam python 3, di bawah ini adalah untuk membuat
*args
dan**kwargs
menjadidict
(gunakanOrderedDict
untuk python <3,6 untuk mempertahankandict
pesanan):sumber
inspect.signature
sangat lambat. Cara tercepat adalahsumber
Untuk memperbarui sedikit memagut jawaban Brian , sekarang ada yang bagus backport dari
inspect.signature
yang dapat Anda gunakan dalam versi python lebih tua:funcsigs
. Jadi preferensi pribadi saya akan berlakuUntuk bersenang-senang, jika Anda tertarik bermain dengan
Signature
objek dan bahkan membuat fungsi dengan tanda tangan acak secara dinamis, Anda dapat melihatmakefun
proyek saya .sumber
Bagaimana
dir()
danvars()
sekarang?Tampaknya melakukan apa yang diminta dengan sangat sederhana ...
Harus dipanggil dari dalam lingkup fungsi.
Tetapi berhati-hatilah karena itu akan mengembalikan semua variabel lokal jadi pastikan untuk melakukannya di awal fungsi jika diperlukan.
Juga perhatikan bahwa, seperti yang ditunjukkan dalam komentar, ini tidak memungkinkan dilakukan dari luar ruang lingkup. Jadi tidak persis skenario OP tetapi masih cocok dengan judul pertanyaan. Karena itu jawabanku.
sumber