Pythonのpyclbrモジュールでクラス・関数情報を抽出する方法を徹底解説
pyclbrモジュールとは
Python標準ライブラリのpyclbrモジュールは、Pythonモジュール内で定義された関数・クラス・メソッドに関する情報を抽出するためのモジュールです。大きな特徴として、対象モジュールを実際にインポートするのではなく、ソースコードを直接解析して情報を取得する点が挙げられます。そのため、インポート時に副作用が発生するようなモジュールでも安全に構造を調査できます。
readmodule()関数でクラス情報を取得する
pyclbrモジュールには、モジュールレベルのクラス名をキー、クラスディスクリプタを値とする辞書を返すreadmodule()関数が用意されています。引数にはモジュール名を指定し、パッケージ内のモジュールを指定する場合は、path引数にsys.pathの先頭へ追加されるディレクトリパスのシーケンスを渡すことで、モジュールのソースコードを検索できます。
以下のコードは、readmodule()関数を使ってPython標準ライブラリのsocketモジュールに含まれるクラスとメソッドを解析する例です。
import pyclbr
mod = pyclbr.readmodule("socket")
def show(c):
s = "class " + c.name
print(s + ":")
methods = c.methods.items()
for method, lineno in methods:
print(" def " + method)
print()
for k, v in mod.items():
show(v)
実行すると、socketモジュール内の各クラスとそのメソッド一覧が出力されます。
class IntEnum:
class IntFlag:
def _missing_
def _create_pseudo_member_
def __or__
def __and__
def __xor__
def __invert__
class _GiveupOnSendfile:
class socket:
def __init__
def __enter__
def __exit__
def __repr__
def __getstate__
def dup
def accept
def makefile
def _sendfile_use_sendfile
def _sendfile_use_send
def _check_sendfile_params
def sendfile
def _decref_socketios
def _real_close
def close
def detach
def family
def type
def get_inheritable
def set_inheritable
class SocketIO:
def __init__
def readinto
def write
def readable
def writable
def seekable
def fileno
def name
def mode
def close
readmodule_ex()関数で関数情報も取得する
pyclbrモジュールには、readmodule_ex()関数も定義されています。この関数は、モジュール内で定義されたすべての関数およびクラスのディスクリプタを含む辞書を返します。戻り値の辞書は、モジュールレベルの関数名・クラス名をそれぞれのディスクリプタへマッピングします。ネストされたオブジェクトは、親オブジェクトのchildren辞書に登録されます。
>>> x = pyclbr.readmodule_ex('socket')
>>> for k,v in x.items():
print(k,v)
IntEnum <pyclbr.Class object at 0x000002095D7D0048>
IntFlag <pyclbr.Class object at 0x000002095D7D04E0>
_intenum_converter <pyclbr.Function object at 0x000002095D82F940>
_GiveupOnSendfile <pyclbr.Class object at 0x000002095D822898>
socket <pyclbr.Class object at 0x000002095D8227B8>
fromfd <pyclbr.Function object at 0x000002095D8340B8>
fromshare <pyclbr.Function object at 0x000002095D82FEF0>
socketpair <pyclbr.Function object at 0x000002095D834128>
SocketIO <pyclbr.Class object at 0x000002095D82FA20>
getfqdn <pyclbr.Function object at 0x000002095D8344E0>
create_connection <pyclbr.Function object at 0x000002095D834518>
getaddrinfo <pyclbr.Function object at 0x000002095D834550>
自作モジュールへの応用
これらの関数は、ユーザーが独自に作成したモジュールに対しても使用でき、自作のクラスやメソッドの一覧を簡単に取得できます。
次の例では、triangles.pyというモジュールからクラス構造を取得します。
#triangles.py
import math
class Triangle:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def area(self):
s = (self.a + self.b + self.c) / 2
area = math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))
return area
class EquiTriangle(Triangle):
def __init__(self, a):
b = a
c = a
super().__init__(a, b, c)
def area(self):
area = math.sqrt(3) * pow(self.a, 2) / 4
return area
それでは、trianglesモジュール内のクラスとメソッドを取得してみましょう。
>>> br = pyclbr.readmodule_ex('triangles')
>>> for i,j in br.items(): print(i, j.methods)
Triangle {'__init__': 3, 'area': 7}
EquiTriangle {'__init__': 12, 'area': 16}
FunctionオブジェクトとClassオブジェクトの属性
pyclbrモジュールは、「Classオブジェクト」と「Functionオブジェクト」の2種類のオブジェクトを定義しています。
Functionオブジェクトの主な属性
| file | 関数が定義されているファイルの名前 |
| module | 対象の関数を定義しているモジュールの名前 |
| name | 関数の名前 |
| lineno | 定義が始まる行の行番号 |
| parent | トップレベル関数の場合はNone、ネストされた関数の場合は親オブジェクト |
| children | ネストされた関数やクラスの名前をディスクリプタにマッピングする辞書 |
Classオブジェクトに追加される属性
Classオブジェクトは、上記の属性に加えて以下の2つの属性を持ちます。
| super | 対象クラスの直接の基底クラスを表すClassオブジェクトのリスト |
| methods | メソッド名を行番号にマッピングする辞書 |
-
Pythonの継承とは?単一継承と階層継承の基本をサンプルコードで解説
本記事では、Python 3.xにおける継承(インヘリタンス)とクラスの拡張方法について詳しく解説します。 継承とは、現実世界のモノや概念の関係性を自然に表現できる、オブジェクト指向プログラミングの中核となる仕組みです。継承を活用すると、次のようなメリットが得られます。 再利用性:すでに書いたコードを流用でき、重複を削減できる 推移性:クラス間の関係を連鎖的に引き継げる 開発速度の向上:ゼロから書かずに済むため、短期間で開発できる 保守性・拡張性:既存クラスを壊さずに機能を追加しやすい 継承の5つの種類 Pythonの継承は、その構造によって主に以下の5種類に分類されます。 単一継承(
-
Pythonの例外基本クラス徹底解説|BaseExceptionと例外階層、独自例外の作り方
Pythonにおける例外とは Pythonには、他の高水準言語と同様に例外(Exception)の仕組みが備わっています。プログラムの実行中に問題が検出されると例外が発生(raise)し、適切に処理しなければプログラムはその時点で中断されます。代表的な例外には、ゼロ除算を表すZeroDivisionErrorや、アサーションの失敗を表すAssertionErrorなど、さまざまな種類があります。 すべての例外クラスはBaseExceptionクラスから派生しています。開発者は組み込みの例外をそのまま利用できるだけでなく、raise文を使ってコード中で意図的に例外を発生させることもできます。さら