Saya mencoba mempelajari cara kerja aplikasi. Dan untuk ini saya memasukkan perintah debug sebagai baris pertama dari setiap tubuh fungsi dengan tujuan untuk mencatat nama fungsi serta nomor baris (di dalam kode) tempat saya mengirim pesan ke output log. Terakhir, karena aplikasi ini terdiri dari banyak file, saya ingin membuat satu file log sehingga saya dapat lebih memahami aliran kontrol aplikasi.
Inilah yang saya ketahui:
untuk mendapatkan nama fungsi, saya dapat menggunakan
function_name.__name__
tetapi saya tidak ingin menggunakan nama_fungsi (sehingga saya dapat dengan cepat menyalin dan menempelkan generikLog.info("Message")
di badan semua fungsi). Saya tahu ini bisa dilakukan di C menggunakan__func__
makro tetapi saya tidak yakin tentang python.untuk mendapatkan nama file dan nomor baris, saya telah melihat itu (dan saya percaya bahwa) aplikasi saya menggunakan
locals()
fungsi Python tetapi dalam sintaks yang saya tidak sepenuhnya sadari misalnya:options = "LOG.debug('%(flag)s : %(flag_get)s' % locals())
dan saya mencobanya menggunakan likeLOG.info("My message %s" % locals())
yang menghasilkan sesuatu seperti{'self': <__main__.Class_name object at 0x22f8cd0>}
. Ada masukan tentang ini?Saya tahu bagaimana menggunakan logging dan menambahkan handler ke dalamnya untuk login ke sebuah file tapi saya tidak yakin apakah satu file dapat digunakan untuk merekam semua pesan log dalam urutan yang benar dari pemanggilan fungsi dalam proyek.
Saya akan sangat menghargai bantuan apa pun.
Terima kasih!
import pdb; pdb.set_trace()
, lalu menelusuri kode secara interaktif. Itu dapat membantu Anda melacak aliran program.Jawaban:
Anda memiliki beberapa pertanyaan yang terkait secara marginal di sini.
Saya akan mulai dengan yang termudah: (3). Menggunakan
logging
Anda dapat menggabungkan semua panggilan ke satu file log atau target keluaran lainnya: panggilan tersebut akan berada dalam urutan yang terjadi dalam proses.Selanjutnya: (2).
locals()
memberikan perintah dari lingkup saat ini. Jadi, dalam metode yang tidak memiliki argumen lain, Anda memilikiself
cakupan, yang berisi referensi ke instance saat ini. Trik yang digunakan yang membingungkan Anda adalah pemformatan string menggunakan dict sebagai RHS%
operator."%(foo)s" % bar
akan diganti dengan apa pun nilainyabar["foo"]
.Terakhir, Anda dapat menggunakan beberapa trik introspeksi, serupa dengan yang digunakan oleh
pdb
yang dapat mencatat lebih banyak info:Ini akan mencatat pesan yang diteruskan, ditambah nama fungsi (asli), nama file di mana definisi tersebut muncul, dan baris di file itu. Lihat inspect - Inspect live object untuk lebih jelasnya.
Seperti yang saya sebutkan dalam komentar saya sebelumnya, Anda juga dapat masuk ke
pdb
prompt debugging interaktif kapan saja dengan memasukkan barisimport pdb; pdb.set_trace()
, dan menjalankan kembali program Anda. Ini memungkinkan Anda untuk menelusuri kode, memeriksa data yang Anda pilih.sumber
'%(foo)s : %(bar)s'
juga akan mencetakbar["foo"]
nilai? Atau apakah itu agak berbeda dari contoh Anda?%(<foo>)s
diganti dengan nilai objek yang direferensikan di dict by<foo>
. Ada lebih banyak contoh / detail di docs.python.org/library/stdtypes.html#string-formattingJawaban yang benar untuk ini adalah dengan menggunakan
funcName
variabel yang telah disediakanLalu di mana pun Anda mau, cukup tambahkan:
Contoh keluaran dari skrip yang saya kerjakan sekarang:
sumber
getLogger(__name__)
logging.getLogger('root')
bukan yang Anda harapkan, ini bukanroot
logger, tetapi logger biasa dengan nama 'root'.funcname
,linename
danlineno
memberikan informasi tentang fungsi terakhir yang melakukan logging.Jika Anda memiliki pembungkus logger (mis. Logger tunggal), maka jawaban @ synthesizerpatel mungkin tidak berfungsi untuk Anda.
Untuk mengetahui penelepon lain dalam tumpukan panggilan, Anda dapat melakukan:
sumber
logging
tingkat dukungan kelas tumpukan skipping out-of-the-box: metode sepertilog()
,debug()
, dll sekarang menerimastacklevel
argumen. Lihat dokumennya .