Geçerli çağrı yığınını Python kodundaki bir yöntemden yazdırma


276

Python'da, geçerli çağrı yığınını bir yöntem içinden nasıl yazdırabilirim (hata ayıklama amacıyla).

Yanıtlar:


319

İşte yığını geri izleme modülü üzerinden alma ve yazdırma örneği :

import traceback

def f():
    g()

def g():
    for line in traceback.format_stack():
        print(line.strip())

f()

# Prints:
# File "so-stack.py", line 10, in <module>
#     f()
# File "so-stack.py", line 4, in f
#     g()
# File "so-stack.py", line 7, in g
#     for line in traceback.format_stack():

Yığını yalnızca stderr'a yazdırmak istiyorsanız, şunu kullanabilirsiniz:

traceback.print_stack()

Veya stdout'a yazdırmak için (yeniden yönlendirilmiş çıktıyı bir arada tutmak istiyorsanız yararlıdır) kullanın:

traceback.print_stack(file=sys.stdout)

Ama üzerinden geçmek, onunla traceback.format_stack()ne istersen yapmana izin verir.


Tüm diğer konular için de aynısını nasıl yapacağım (Kontrol etmediğim konular hakkında konuşuyorum)  ?
user2284570

Belki burada bir şey eksik, ama sen f diyorsun tek amacı burada g aramak ve başka bir şey yapmaz. Neden
Chris

6
@Chris: Bu sadece bir örnek. Format_stack () öğesinin yığındaki tüm çağrıları yazdırdığını netleştirmek için birden fazla işlevi vardır.
RichieHindle

Biraz daha ayrıntılı çıktı (vars vb. Dahil) almak istiyorsanız, bu ilgili soruya ve buna bakın .
Albert

@ user2284570: Kullanabilirsiniz sys._current_frames(). Örneğin py_better_exchookdump_all_thread_tracebacks bunu yapar (feragatname: Bunu ben yazdım).
Albert

93
import traceback
traceback.print_stack()

8
Aslında, traceback.print_exc()hangi exceptifadeyi almadan alacağınızla aynı şeyi verir (ve aynı zamanda kabul edilen cevaptan daha az kodlama yapar).
martineau

34
traceback.print_exc()işleyebileceğiniz herhangi bir istisna için yığın izini yazdırır - ancak bu, geçerli yığının nasıl yazdırılacağı anlamına gelmez; kapalı, varsa ".)
Tom Swirly


17

Eğer python hata ayıklayıcı kullanıyorsanız, sadece değişkenlerin interaktif problaması değil, aynı zamanda çağrı yığınını "where" komutu veya "w" ile alabilirsiniz.

Programınızın en üstünde

import pdb

Sonra neler olduğunu görmek istediğiniz kodda

pdb.set_trace()

ve bir istemin içine düştün


2
On yıldan uzun bir süredir Python'da program yapıyorum. Orada öylesine bunu kullandım olabilirdi defalarca! Şimdi bunu öğrendiğime inanamıyorum.
hosford42

1
Bu nasıl bir ilişkidir where?
skia.heliou

4
Sorunun "nerede" bölümünü cevaplamak için: pdb istemi aldıktan sonra (pdb) sadece tipini whereve terminale yığın izlemesini yazdırır.
stephenmm

1
Python 3.7 ve üstü, breakpoint()pdb alma ihtiyacını ortadan kaldıran yerleşik bir işleve sahiptir.
user650654

6

pdb kullanırken çağrı yığınını yazdırmak isteyenler için,

(Pdb) where

2

@ RichieHindle'ın fonksiyonlara istendiği gibi seçici olarak uygulanabilen bir dekoratörü uygulayan mükemmel cevabının bir varyasyonu. Python 2.7.14 ve 3.6.4 ile çalışır.

from __future__ import print_function
import functools
import traceback
import sys

INDENT = 4*' '

def stacktrace(func):
    @functools.wraps(func)
    def wrapped(*args, **kwds):
        # Get all but last line returned by traceback.format_stack()
        # which is the line below.
        callstack = '\n'.join([INDENT+line.strip() for line in traceback.format_stack()][:-1])
        print('{}() called:'.format(func.__name__))
        print(callstack)
        return func(*args, **kwds)

    return wrapped

@stacktrace
def test_func():
    return 42

print(test_func())

Numune çıktısı:

test_func() called:
    File "stacktrace_decorator.py", line 28, in <module>
    print(test_func())
42

Bunu görmeden önce kendi dekoratör versiyonumu yazdım. Upvoted.
Sida Zhou

0

Inspect-it'i yükleyin

pip3 install inspect-it --user

kod

import inspect;print(*['\n\x1b[0;36;1m| \x1b[0;32;1m{:25}\x1b[0;36;1m| \x1b[0;35;1m{}'.format(str(x.function), x.filename+'\x1b[0;31;1m:'+str(x.lineno)+'\x1b[0m') for x in inspect.stack()])

bu satırın bir pasajını yapabilirsiniz

size dosya adı ve satır numarası ile fonksiyon çağrısı yığınının bir listesini gösterecektir

Başlangıçtan bu satırı nereye koyacağınıza

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.