13

から派生した、Python 2.7 で独自の例外クラスを定義しようとしましたBaseException

class NestedCommentException(BaseException):
    """
    Exception for nested comments
    """
    def __init__(self, file_path, list_lines):
        self.file_path = file_path
        self.list_lines = list_lines

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        return 'File {0} contains nested comments at lines {1}'.format(self.file_path, ', '.join(self.list_lines))

しかし、それを投げるとき、それは印刷できません:raise NestedCommentException(file_path, list_lines)トリガー

Traceback (most recent call last):
  File "D:\DATA\FP12210\My Documents\Outils\SVN\05_impl\2_tools\svn_tag_setup.py", line 85, in <module>
    tag_checks()
  File "D:\DATA\FP12210\My Documents\Outils\SVN\05_impl\2_tools\svn_tag_setup.py", line 66, in tag_checks
    check_nested_comments(ddl_path)
  File "D:\DATA\FP12210\My Documents\Outils\SVN\05_impl\2_tools\svn_tag_setup.py", line 54, in check_nested_comments
    raise NestedCommentException(file_path, list_lines)
NestedCommentException: <unprintable NestedCommentException object>

__str__and__repr__メソッドを定義したとしても、なぜこれが起こるのか説明してもらえますか?

4

2 に答える 2

12

TL;DR

これが表示された場合、基本的には、オブジェクトで何らかの例外が発生したことを意味し__str__()ます。したがって、問題が一目でわかるほど些細な問題でない限り (例: "%s" を忘れた)、

  • __str__Anurag のアドバイスとして、本体を try/except 句でラップするか、または

  • __str__例外をインスタンス化し、traceback モジュールの外部で手動で (またはオーバーライドした可能性のあるメソッド) を呼び出して、例外の完全な説明を取得します。

分析

実際<unprintable MyException object>には、これは traceback モジュールのさまざまな関数から発生する可能性があり、値の文字列 (つまり「印刷可能」) バージョンを取得しようとすると (例外)、

  1. それを呼び出しstr()、何か問題が発生した場合は、

  2. Unicode として扱い、ASCII に変換しようとしますが、それでも問題が解決しない場合は

  3. 上記の表現を単純に出力します。

責任あるコード (2.6 と 2.7 で同じ):

def _some_str(value):
    try:
        return str(value)
    except Exception:
        pass
    try:
        value = unicode(value)
        return value.encode("ascii", "backslashreplace")
    except Exception:
        pass
    return '<unprintable %s object>' % type(value).__name__

ご覧のとおり、呼び出しまたは呼び出しから発生する例外はプロセスで中止され、「不可解な」表現のみが提供されます。str()unicode.encode()

traceback モジュールと Python インタープリターに関する注意事項

tracebackドキュメントが教えてくれることとは反対に:

スタック トレースを出力するときの Python インタープリターの動作を正確に模倣します。

ここでは、Python インタープリターによって提供される表現が少し異なります。「unprintable」メッセージとは対照的に、インタープリターは単に例外の名前を表示し、実際の例外も停止します。

これは、 Python インタープリターに例外を残す、traceback モジュールを使用する、または関数を手動で呼び出すという 3 つのアプローチすべてを示す簡単なスクリプトです。

#!/usr/bin/python

import sys, traceback

class Boom(Exception):

    def __init__(self, foo, bar, baz):
        self.foo, self.bar, self.baz = foo, bar, baz

    def __str__(self):
        return ("boom! foo: %s, bar: %s, baz: "     # ouch! forgot an %s!
                % (self.foo, self.bar, self.baz))

def goBoom(): raise Boom(foo='FOO', bar='BAR', baz='BAZ')

if __name__ == "__main__":

    if sys.argv[1].startswith("i"):
        goBoom()
        # __main__.Boom

    elif sys.argv[1].startswith("t"):
        try:    goBoom()
        except: traceback.print_exc(file=sys.stdout)
        # Boom: <unprintable Boom object>

    elif sys.argv[1].startswith("m"):
        e = Boom(foo='FOO', bar='BAR', baz='BAZ')
        e.__str__()
        # TypeError: not all arguments converted during string formatting

    else: pass
于 2013-09-23T13:43:45.047 に答える
8

私の推測では、ユニコード機能のないコンソールに印刷されていないユニコードfile_pathまたは変数が原因であると思います。list_lines

またはその他の例外__str__がこのような奇妙な動作を引き起こす可能性があります。最善の方法は、例外をキャッチして何が起こっているかを確認することです。デバッガも使用してください

def __str__(self):
    try:
        s =  'File {0} contains nested comments at lines {1}'.format(self.file_path, ', '.join(self.list_lines))
    except Exception,e:
        print "-----",type(e),e
    return s
于 2012-10-26T15:32:25.437 に答える