はじめに
Twitterで一時期流行していた 100 Days Of Code なるものを先日知りました。本記事は、初学者である私が100日の学習を通してどの程度成長できるか記録を残すこと、アウトプットすることを目的とします。誤っている点、読みにくい点多々あると思います。ご指摘いただけると幸いです!
今回学習する教材
-
- 8章構成
- 本章216ページ
-
第8章:本番運用準備
出力のデバッグには、repr文字列を使う
デバッグするときに、変数の型の状態を知りたいときはよくあると思います。
しかし、print関数に数値を渡しても文字列を渡しても、同じ出力になります。
print(5)
print('5')
実行結果
5
5
組み込み関数reprは、オブジェクトの印字可能な表現を返します。
reprを使うことにより、数値か文字列か判別できます。
print(repr(5))
print(repr('5'))
実行結果
5
'5'
オブジェクトインスタンスの中身を確認したいときがあると思います。
class OpaqueClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
obj = OpaqueClass(1, 2)
print(obj)
# <__main__.OpaqueClass object at 0x000001D9C19EDF88>
これだと、オブジェクトのインスタンスフィールドについての情報が無いですね。
この問題を解決する方法は2つあります。
1つ目は、__repr__
メソッドを定義して、オブジェクトを複製するPython式を含んだ文字列を返すことです。
class BetterClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'BetterClass(%d, %d)' % (self.x, self.y)
obj = BetterClass(1, 2)
print(obj)
# BetterClass(1, 2)
2つ目は、__dict__
属性に格納されているオブジェクトのインスタンス辞書にアクセスすることです。
class OpaqueClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
obj = OpaqueClass(1, 2)
print(obj.__dict__)
# {'x': 1, 'y': 2}
pdbで対話的にデバッグすることを考える
Pythonの組み込み対話的デバッガを試用することで、プログラムの状態を調べ、ローカル変数を印刷し、Pythonプログラムのステップ実行ができます。
def sample_func(a, b, c):
import pdb; pdb.set_trace()
a *= 2
b *= 3
sample_func(1, 2, 3)
この分が実行されると、プログラムは実行を一時停止します。
プログラムを開始した端末は、対話的Pythonシェルになります。
-> a *= 2
(Pdb) a
(Pdb) プロンプトの後で、ローカル変数を入力すると、その値が出力されます。
(Pdb) locals()
{'a': 1, 'b': 2, 'd': 3, 'pdb': <module 'pdb' from ...
デバッガには、実行されているプログラムを調べるのを容易にするコマンドや、再開するコマンドなど多数の機能があります。
- bt 現在の実行呼び出しスタックのトレースバックを印刷する
- up スコープを呼び出しスタックから現在の関数の呼び出し元に移す
- down スコープを関数呼び出しスタックの1段下に移す
- step プログラムを次の行まで実行し、制御をでばっかに戻す
- next プログラムを現在の関数の次の行まで実行し、制御をデバッガに戻す
- return プログラムを現在の関数から復帰するまで実行し、制御をデバッガに戻す
- continue プログラムをpdb.set_traceが再度呼ばれるまで実行し続ける