কিভাবে একটি চলক মধ্যে traceback / sys.exc_info () মান সংরক্ষণ করতে?


127

আমি ত্রুটির নাম এবং ট্রেসব্যাকের বিশদটি একটি ভেরিয়েবলে সংরক্ষণ করতে চাই। এখানে আমার চেষ্টা।

import sys
try:
    try:
        print x
    except Exception, ex:
        raise NameError
except Exception, er:
    print "0", sys.exc_info()[0]
    print "1", sys.exc_info()[1]
    print "2", sys.exc_info()[2]

আউটপুট:

0 <type 'exceptions.NameError'>
1 
2 <traceback object at 0xbd5fc8>

পছন্দসই আউটপুট:

0 NameError
1
2 Traceback (most recent call last):
  File "exception.py", line 6, in <module>
    raise NameError

PS আমি জানি এটি ট্রেসব্যাক মডিউলটি ব্যবহার করে সহজেই করা যায় তবে আমি এখানে sys.exc_info () [2] অবজেক্টের ব্যবহার জানতে চাই।


আপনি কি sys.exc_info () [x] .__ str __ () মুদ্রণের চেষ্টা করেছেন?
zmbq

3
আপনার প্রোগ্রামে যা চলছে তা আপনি ভুল বুঝতে পেরেছেন: "sys.exc_info () [2] অবজেক্ট" হিসাবে আপনি যাকে উল্লেখ করেন এটি ট্রেসব্যাক অবজেক্টের একটি উদাহরণ (আপনি ইতিমধ্যে ট্রেসব্যাক মডিউলটি ব্যবহার করছেন)। এখন, আপনি ট্রেসব্যাক মডিউলে সহায়ক ফাংশনগুলি ব্যবহার না করেই সেই অবজেক্টটি ম্যানিপুলেট করতে পারেন, তবে আপনি এখনও এটি ব্যবহার করছেন এমন সত্যটি পরিবর্তিত হয় না। :)
ম্যাক

1
সুতরাং @ ম্যাক দয়া করে সাহায্যকারী ফাংশনটি ব্যবহার না করে বা এই অবজেক্ট থেকে মানটি অ্যাক্সেস করতে আমাকে সহায়তা করুন।
কোডারসোফিডার্ক

1
@ ডিগ্রোসরস্পেরকুল - যেমনটি আমি নীচে আমার উত্তরে উল্লেখ করেছি, আপনার ট্রেসব্যাক ডকুমেন্টেশনের দিকে নজর দেওয়া উচিত । আমি কীভাবে ডেটা টেক্সটিক্যালি তথ্য পুনরুদ্ধার করেছিলাম তার একটি উদাহরণ দিয়েছি, তবে অবজেক্টের অন্যান্য পদ্ধতি রয়েছে যা আপনাকে ব্যতিক্রম নাম, কোডের সারি ইত্যাদি নিষ্কাশনের অনুমতি দেয় ... ডানটি কীভাবে আপনি কীভাবে পরিচালনা করতে চান তার উপর নির্ভর করে এর পরে মান ...
ম্যাক

1
আমার অন্য প্রশ্নের উত্তর উত্তরগুলিতে চিত্রিত করতে সহায়তা করতে পারে - লিঙ্কগুলি সহ! ক্যানড স্ট্রিংগুলির জন্য, স্ট্যান্ডার্ড লাইব্রেরির ট্রেসব্যাক মডিউলটি ঠিক আছে বলে মনে হচ্ছে। আপনি যদি বিশদটি পেতে চান তবে <python install path>/Lib/traceback.pyআরও তথ্যের জন্য উত্সটি ( ) পড়ুন।
পাইথোনালারি

উত্তর:


180

আমি এটি এইভাবে করি:

>>> import traceback
>>> try:
...   int('k')
... except:
...   var = traceback.format_exc()
... 
>>> print var
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: invalid literal for int() with base 10: 'k'

তবে আপনার অনুসরণীয় প্রক্রিয়াটি কীভাবে প্রক্রিয়াকরণ করতে চান তার উপর নির্ভর করে আপনি সেখানে আরও উপযুক্ত পদ্ধতি খুঁজে পেতে পারেন, তবে ট্রেসব্যাক ডকুমেন্টেশনটি একবার দেখে নেওয়া উচিত ...


1
আমি ট্রেসব্যাক মডিউলটি ব্যবহার না করেই কোনও পদ্ধতির সন্ধান করছিলাম। সেখানে কি কোনওভাবে আমরা এই অবজেক্টের রেফারেন্স থেকে কেবল ট্রেস-ব্যাক বিশদটি মুদ্রণ করতে পারি? sys.exc_info () [2]
কোডারসোফিডার্ক

ঠিক তাই, আমি ভেবেছিলাম যে আমরা sys.exc_info () [2]। Formatt_exc () এর মতো কিছু করতে পারি, তবে এটি কাজ করে না .. সুতরাং আমি কীভাবে ট্রেস-ব্যাক অবজেক্ট sys.exc_info () থেকে মান বের করতে পারি তা ভাবছি [2]। কোন ধারণা?
কোডারসোফিডার্ক

1
sys.exc_info () [2] .tb_text ফলো ত্রুটি দেয় -> বৈশিষ্ট্য ত্রুটি: 'ট্রেসব্যাক' অবজেক্টটির 'tb_text' এর কোনও বৈশিষ্ট্য নেই
codersofthedark

4
@ ডিগ্রোসরাসুপার্কুল - sys.exc_info()[2].tb_frame.f_code.co_names[3]তবে এটি যে কোনওভাবেই বোঝায় না ... tracebackস্ট্যান্ডার্ড লাইব্রেরিতে যদি কোনও মডিউল বলা হয় তবে এর কারণ আছে ... :)
ম্যাক

2
@ কোডারসোফিডার্ক traceback.format_exception(*sys.exc_info())এটি করার উপায়। তবে এটি কার্যত সমান traceback.format_exc()
wizzwizz4

25

sys.exc_info () তিনটি মান (প্রকার, মান, ট্রেসব্যাক) সহ একটি টুপল দেয়।

  1. এখানে টাইপ ব্যতিক্রম হ্যান্ডেল করা ব্যতিক্রম টাইপ পায়
  2. মান হ'ল আর্গুমেন্টগুলি যা ব্যতিক্রম শ্রেণীর নির্মাতাকে দেওয়া হচ্ছে
  3. ট্রেসব্যাকে স্ট্যাকের তথ্য রয়েছে যেখানে ব্যতিক্রম কোথায় ঘটেছিল ইত্যাদি contains

উদাহরণস্বরূপ, নিম্নলিখিত প্রোগ্রামে

try:

    a = 1/0

except Exception,e:

    exc_tuple = sys.exc_info()

এখন আমরা টিপল মুদ্রণ করা মান মান হবে।

  1. exc_tuple [0] মানটি " জিরো ডিভিশনইরির " হবে
  2. exc_tuple [1] মানটি হবে " পূর্ণসংখ্যা বিভাগ বা শূন্য দ্বারা মডুলো " (স্ট্রিং ব্যতিক্রম পরামিতি হিসাবে প্যারামিটার হিসাবে পাস হয়েছে)
  3. exc_tuple [2] মান হবে " ট্র্যাকব্যাক অবজেক্ট এ (কিছু মেমরি ঠিকানা) "

উপরের বিশদগুলি স্ট্রিং ফর্ম্যাটে কেবল ব্যতিক্রম মুদ্রণ করেও পাওয়া যায়।

print str(e)

পাইথন 3 এর জন্য, এক্স_টুপল [1] (ওরফে মান) ব্যতিক্রমের উদাহরণ , "স্ট্রিংটিকে প্যারামিটার হিসাবে পাস করা হয় না"। দেখুন: docs.python.org/3/library/sys.html#sys.exc_info
Jinghao Shi

এটি "ই হিসাবে ব্যতিক্রম ছাড়া" হওয়া উচিত নয়?
হেনরিক

20

traceback.extract_stack()আপনি যদি মডিউল এবং ফাংশনের নাম এবং লাইন নম্বরগুলিতে সুবিধাজনক অ্যাক্সেস চান তবে ব্যবহার করুন ।

''.join(traceback.format_stack())আপনি যদি traceback.print_stack()আউটপুটটির মতো দেখতে একটি স্ট্রিং চান তবে ব্যবহার করুন ।

লক্ষ্য করুন যে এমনকি আপনার সাথে ''.join()একটি মাল্টি-লাইন স্ট্রিং পাবেন, যেহেতু উপাদানগুলির উপাদান format_stack()রয়েছে \n। নীচে আউটপুট দেখুন।

মনে আছে import traceback

এখানে থেকে আউটপুট traceback.extract_stack()। বিন্যাস পাঠযোগ্যতার জন্য যুক্ত করা হয়েছে।

>>> traceback.extract_stack()
[
   ('<string>', 1, '<module>', None),
   ('C:\\Python\\lib\\idlelib\\run.py', 126, 'main', 'ret = method(*args, **kwargs)'),
   ('C:\\Python\\lib\\idlelib\\run.py', 353, 'runcode', 'exec(code, self.locals)'),
   ('<pyshell#1>', 1, '<module>', None)
]

এখানে থেকে আউটপুট ''.join(traceback.format_stack())। বিন্যাস পাঠযোগ্যতার জন্য যুক্ত করা হয়েছে।

>>> ''.join(traceback.format_stack())
'  File "<string>", line 1, in <module>\n
   File "C:\\Python\\lib\\idlelib\\run.py", line 126, in main\n
       ret = method(*args, **kwargs)\n
   File "C:\\Python\\lib\\idlelib\\run.py", line 353, in runcode\n
       exec(code, self.locals)\n  File "<pyshell#2>", line 1, in <module>\n'

4

আপনি যখন ব্যতিক্রম হ্যান্ডলারটি থেকে ব্যতিক্রম বস্তু বা ট্রেসব্যাক অবজেক্টটি গ্রহণ করেন তখন সাবধান হন, যেহেতু এটি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সের কারণ এবং gc.collect()এটি সংগ্রহ করতে ব্যর্থ হবে। এই প্রদর্শিত হয় যেখানে ট্রেসব্যাক বস্তুর সঠিক সময়ে সাফ না হয়ে যায় এবং এমনকি একটি সুনির্দিষ্ট থেকে কল ipython / jupyter নোটবুক পরিবেশে একটি নির্দিষ্ট সমস্যা হতে gc.collect()মধ্যে finallyঅধ্যায় কিছুই করে না। এবং এটি একটি বিশাল সমস্যা যদি আপনার কিছু বিশাল অবজেক্ট থাকে যার কারণে তাদের স্মৃতি পুনরুদ্ধার না করে (যেমন CUDA এর থেকে মেমরি ব্যতিক্রম রয়েছে যে ডাব্লু / ও এই সমাধানটির পুনরুদ্ধারের জন্য একটি সম্পূর্ণ কার্নেল পুনরায় সূচনা প্রয়োজন)।

সাধারণভাবে আপনি যদি ট্রেসব্যাক অবজেক্টটি সংরক্ষণ করতে চান তবে আপনাকে এটির locals()মতো রেফারেন্স থেকে সাফ করা দরকার :

import sys, traceback, gc
type, val, tb = None, None, None
try:
    myfunc()
except:
    type, val, tb = sys.exc_info()
    traceback.clear_frames(tb)
# some cleanup code
gc.collect()
# and then use the tb:
if tb:
    raise type(val).with_traceback(tb)

জুপিটার নোটবুকের ক্ষেত্রে আপনাকে ব্যতিক্রম হ্যান্ডলারের ভিতরে খুব কম সময়ে এটি করতে হবে:

try:
    myfunc()
except:
    type, val, tb = sys.exc_info()
    traceback.clear_frames(tb)
    raise type(val).with_traceback(tb)
finally:
    # cleanup code in here
    gc.collect()

অজগর ৩. 3. দিয়ে পরীক্ষা করা হয়েছে।

আইপিথন বা জুপিটার নোটবুক এনভির সাথে সমস্যাটি হ'ল এটিতে এমন %tbম্যাজিক রয়েছে যা ট্রেসব্যাক সংরক্ষণ করে এবং যেকোন সময় পরে এটি উপলব্ধ করে available এবং ফলস্বরূপ locals()ট্রেসব্যাকে অংশ নেওয়া সমস্ত ফ্রেমের যে কোনওটি নোটবুকটি প্রস্থান না করা বা অন্য কোনও ব্যতিক্রম পূর্ববর্তী সঞ্চিত ব্যাকট্র্যাসটি ওভাররাইট না করা পর্যন্ত মুক্তি পাবে না। এটি খুব সমস্যাযুক্ত। এটি ফ্রেমগুলি পরিষ্কার করে ট্রেসব্যাক ডাব্লু / ও সংরক্ষণ করা উচিত নয়। এখানে জমা দেওয়া ঠিক করুন


3

বস্তুটি Exception.with_traceback()ফাংশনে প্যারামিটার হিসাবে ব্যবহার করা যেতে পারে :

except Exception as e:
    tb = sys.exc_info()
    print(e.with_traceback(tb[2]))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.