पायथन कोड में एक विधि से वर्तमान कॉल स्टैक प्रिंट करें


276

पायथन में, मैं एक विधि के भीतर से मौजूदा कॉल स्टैक को कैसे प्रिंट कर सकता हूं (डिबगिंग उद्देश्यों के लिए)।

जवाबों:


319

यहाँ ट्रेसबैक मॉड्यूल के माध्यम से स्टैक प्राप्त करने और इसे प्रिंट करने का एक उदाहरण दिया गया है:

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():

यदि आप वास्तव में स्टाडर को स्टैक प्रिंट करना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:

traceback.print_stack()

या stdout में प्रिंट करने के लिए (उपयोगी अगर पुनर्निर्देशित आउटपुट को एक साथ रखना चाहते हैं), का उपयोग करें:

traceback.print_stack(file=sys.stdout)

लेकिन इसके माध्यम traceback.format_stack()से प्राप्त करना आपको इसके साथ जो कुछ भी पसंद है उसे करने देता है।


अन्य सभी थ्रेड्स के लिए समान कैसे करें (मैं उन थ्रेड्स के बारे में बात कर रहा हूं जिन्हें मैं नियंत्रित नहीं करता हूं)  ?
user2284570

हो सकता है कि मैं यहाँ कुछ याद कर रहा हूँ, लेकिन आप f को कॉल करते हैं जिसका उद्देश्य केवल यहाँ है, कॉल को g करना और कुछ नहीं करना है। क्यों
क्रिस

6
@ क्रिस: यह सिर्फ एक उदाहरण है। यह स्पष्ट करने के लिए कई कार्य हैं कि format_stack () स्टैक पर सभी कॉल प्रिंट करता है।
रिचीहिंडल

यदि आप कुछ और वर्बोज़ आउटपुट (vars आदि सहित) प्राप्त करना चाहते हैं, तो संबंधित प्रश्न और यह देखें
अल्बर्ट

@ user2284570: आप उपयोग कर सकते हैं sys._current_frames()। जैसे py_better_exchookdump_all_thread_tracebacks करता है (अस्वीकरण: मैंने लिखा है कि)।
अल्बर्ट

93
import traceback
traceback.print_stack()

8
वास्तव में, मुझे पसंद है traceback.print_exc()जो आपको लगभग वही चीज देता है जो आपने exceptबयान के बिना प्राप्त की होगी (और स्वीकृत उत्तर की तुलना में कम कोडिंग भी है)।
मार्टीन्यू

34
traceback.print_exc()किसी भी अपवाद के लिए स्टैक ट्रेस को प्रिंट करता है जिसे आप संभाल रहे होंगे - लेकिन यह मूल प्रश्न को हल नहीं करता है, जो कि वर्तमान स्टैक को प्रिंट करने का तरीका है ("जहां अब आप हैं" के विपरीत "जहां आपका कोड आखिरी अपवाद था, वहां" बंद, अगर कोई "।)
टॉम स्विरली


17

यदि आप अजगर डीबगर का उपयोग करते हैं, तो न केवल चर की संवादात्मक जांच, बल्कि आप "जहां" कमांड या "डब्ल्यू" के साथ कॉल स्टैक प्राप्त कर सकते हैं।

तो अपने कार्यक्रम के शीर्ष पर

import pdb

फिर उस कोड में जहां आप देखना चाहते हैं कि क्या हो रहा है

pdb.set_trace()

और आप एक संकेत में गिरा दिया


2
मैं पायथन में एक दशक से अधिक समय से प्रोग्रामिंग कर रहा हूं। कर रहे हैं तो कई बार मैं इस का इस्तेमाल किया है सकते हैं! मुझे विश्वास नहीं हो रहा है कि मैं अभी इसके बारे में पता लगा रहा हूँ।
hosford42

1
यह किस तरह से संबंधित है where?
skia.heliou

4
प्रश्न का "कहाँ" भाग का उत्तर देने के लिए: आपके द्वारा pdb प्रॉम्प्ट को (pdb) बस टाइप करने के बाद whereऔर यह स्टैक ट्रेस को टर्मिनल पर प्रिंट करेगा।
स्टीफनmm

1
पायथन 3.7 और इसके बाद के संस्करण में एक बिल्डिन फ़ंक्शन होता है breakpoint()जो पीडीबी आयात करने की आवश्यकता को पूरा करता है।
उपयोगकर्ता 650654

6

उन लोगों के लिए जिन्हें पीडीबी का उपयोग करते समय कॉल स्टैक को प्रिंट करने की आवश्यकता है, बस

(Pdb) where

2

यहां @ रिचीहिंडले के उत्कृष्ट उत्तर की विविधता है जो एक डेकोरेटर को लागू करता है जिसे चुनिंदा रूप से वांछित कार्यों के लिए लागू किया जा सकता है। पायथन 2.7.14 और 3.6.4 के साथ काम करता है।

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())

नमूने से आउटपुट:

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

यह देखने से पहले मैंने अपना डेकोरेटर संस्करण लिखा। Upvoted।
सिडा झोउ

0

इंस्पेक्शन-इट स्थापित करें

pip3 install inspect-it --user

कोड

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()])

आप इस लाइन का एक स्निपेट बना सकते हैं

यह आपको फ़ाइल नाम और लाइन नंबर के साथ फ़ंक्शन कॉल स्टैक की एक सूची दिखाएगा

शुरू से सूची जहाँ आप इस लाइन डाल दिया

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.