betterway 75デバッグ出力再生文字列を使用

3177 ワード

デバッグ出力でrepr文字列を使用する


デバッグ


  • デバッグは、エラー(エラー)の位置を特定して分析し、正しく修復するプロセスです.

  • Pythonプログラムをデバッグするときにprint関数とフォーマット文字列を使用するか、ログ内蔵モジュールを使用して出力を作成すると、長い出力が発生します.

  • 私たちがしなければならない仕事は、プログラムの実行時にprintを呼び出し、ステータスがどのように変化したのか、エラーが何なのかを知ることです.
  • print関数は、パラメータとして受信したターゲットを読み取り可能な文字列として表示します。

  • 例えば、デフォルト文字列が出力される場合、出力内容は引用符ではなく
  • である.
    print('foo 뭐시기')
    何?
    いろいろな方法を使うのも同じです.
    my_value = 'foo 뭐시기'
    print(str(my_value))
    print('%s' % my_value)
    print(f'{my_value}')
    print(format(my_value))
    print(my_value.__format__('s'))
    print(my_value.__str__())

    問題は,どの値を読み取り可能な文字列に変換しても,その値の実際のタイプと具体的な構成を明確にすることは困難である.


    たとえば
  • ではprintの基本出力を使用すると、5と5の2つの文字列タイプを区別するのは難しい.
  • print(5)
    print('5')
    
    int_value = 5
    str_value = '5'
    print(f'{int_value} == {str_value} ?')
    5
    5
    5 == 5 ?

    デバッグ中にprintを使用すると、このタイプの違いが問題になります。

  • をデバッグする場合、必要な文字列のほとんどは、オブジェクトのバージョンを再生形式で表示します.
  • repr内蔵関数はオブジェクトの出力可能表現を返し、出力可能表現はオブジェクトを最も明確に理解する文字列表現でなければならない.
  • a = '\x07'
    print(repr(a))
    '\x07'
    print(a)
    reprが返す値をeval内蔵関数に渡すと、reprに渡されるオブジェクトと同じオブジェクトが生成されます.
    b = eval(repr(a))
    print(b)
    assert a == b
    printを使用してデバッグする場合は、出力値の前にreprを呼び出す必要があります.これにより、タイプが異なる場合でも差異が明確に表示されます.
    print(repr(5))
    print(repr('5'))
    5
    '5'
    呼び出しreprは%演算子に対して%rを使用して文字列を形式化するか、f-文字列に対してか!rタイプ変換と同じです.
    print('%r' % 5)
    print('%r' % '5')
    
    int_value = 5
    str_value = '5'
    print(f'{int_value!r} != {str_value!r}')
    5
    '5'
    5 != '5'
    例えば、Pythonクラスの場合、人間が読み取ることができる文字列値は再生値と同じである.これは、インスタンスをprintにダンプすると、必要な出力が出力されるため、インスタンスにreprを呼び出す必要がないことを意味する.残念なことに,objectのサブクラスを継承するreprの基本実装はあまり役に立たない.
    たとえば、次のコードは、単純なクラスを定義し、クラスのインスタンスを出力します.
    class OpaqueClass:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
    obj = OpaqueClass(1, 'foo')
    print(obj)

    この出力はeval関数には渡されず、オブジェクトインスタンスフィールドに関する情報も含まれません.
  • の問題を解決する2つの方法
    -クラスソースコードを変更できる場合は、オブジェクトを再生成するPython文字列を返すrepr特殊メソッドを直接定義できます.
    -前に見たクラスにreprの特殊なメソッドを定義したコードを次に示します.
  • class BetterClass:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def __repr__(self):
            return f'BetterClass({self.x!r}, {self.y!r})'
        
    obj = BetterClass(2, '뭐시기')
    print(obj)
    BetterClass(2,「なに」)
  • クラス定義を任意に変更できない場合は、dictでアクセスオブジェクトのインスタンスリストを宣言できます.
  • 以下のコードは、OpaqueClassインスタンスの内容を出力する.
  • obj = OpaqueClass(4, 'baz')
    print(obj.__dict__)
    {'x': 4, 'y': 'baz'}