Misalkan myapp/foo.py
mengandung:
def info(msg):
caller_name = ????
print '[%s] %s' % (caller_name, msg)
Dan myapp/bar.py
berisi:
import foo
foo.info('Hello') # => [myapp.bar] Hello
Saya ingin caller_name
disetel ke __name__
atribut modul fungsi pemanggil (yaitu 'myapp.foo') dalam kasus ini. Bagaimana ini bisa dilakukan?
python
stack-trace
introspection
Sridhar Ratnakumar
sumber
sumber
caller_name
tidak dapat__main__
Jawaban:
Lihat modul inspeksi:
inspect.stack()
akan mengembalikan informasi tumpukan.Di dalam suatu fungsi,
inspect.stack()[1]
akan mengembalikan tumpukan pemanggil Anda. Dari sana, Anda bisa mendapatkan lebih banyak informasi tentang nama fungsi pemanggil, modul, dll.Lihat dokumen untuk detailnya:
http://docs.python.org/library/inspect.html
Juga, Doug Hellmann memiliki tulisan bagus tentang modul inspeksi dalam seri PyMOTW-nya:
http://pymotw.com/2/inspect/index.html#module-inspect
EDIT: Berikut beberapa kode yang melakukan apa yang Anda inginkan, menurut saya:
sumber
__name__
atribut modul ini menggunakaninspect
modul? Misalnya, bagaimana saya mendapatkan kembalimyapp.foo
(bukanmyapp/foo.py
) dalam contoh saya di atas? Saya sudah mencoba menggunakan modul inspeksi sebelum memposting di SO.inspect.stack()[2]
pemanggil yang sebenarnya.Dihadapkan dengan masalah serupa, saya telah menemukan bahwa sys._current_frames () dari modul sys berisi informasi menarik yang dapat membantu Anda, tanpa perlu mengimpor inspeksi, setidaknya dalam kasus penggunaan tertentu.
Anda kemudian dapat "naik" menggunakan f_back:
Untuk nama file Anda juga bisa menggunakan f.f_back.f_code.co_filename, seperti yang disarankan oleh Mark Roddy di atas. Saya tidak yakin dengan batasan dan peringatan dari metode ini (beberapa utas kemungkinan besar akan menjadi masalah) tetapi saya bermaksud menggunakannya dalam kasus saya.
sumber
sys._getframe(1)
, daripada memanggilsys._current_frames()
(btw yang mengembalikan pemetaan bingkai untuk setiap utas).inspect.currentframe()
daripadasys._current_frames().values()[0]
.Saya tidak menyarankan melakukan ini, tetapi Anda dapat mencapai tujuan Anda dengan metode berikut:
Kemudian perbarui metode yang ada sebagai berikut:
sumber
__name__