Python
 Computer >> コンピューター >  >> プログラミング >> Python

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メソッド名を行番号にマッピングする辞書
  1. Pythonの継承とは?単一継承と階層継承の基本をサンプルコードで解説

    本記事では、Python 3.xにおける継承(インヘリタンス)とクラスの拡張方法について詳しく解説します。 継承とは、現実世界のモノや概念の関係性を自然に表現できる、オブジェクト指向プログラミングの中核となる仕組みです。継承を活用すると、次のようなメリットが得られます。 再利用性:すでに書いたコードを流用でき、重複を削減できる 推移性:クラス間の関係を連鎖的に引き継げる 開発速度の向上:ゼロから書かずに済むため、短期間で開発できる 保守性・拡張性:既存クラスを壊さずに機能を追加しやすい 継承の5つの種類 Pythonの継承は、その構造によって主に以下の5種類に分類されます。 単一継承(

  2. Pythonの例外基本クラス徹底解説|BaseExceptionと例外階層、独自例外の作り方

    Pythonにおける例外とは Pythonには、他の高水準言語と同様に例外(Exception)の仕組みが備わっています。プログラムの実行中に問題が検出されると例外が発生(raise)し、適切に処理しなければプログラムはその時点で中断されます。代表的な例外には、ゼロ除算を表すZeroDivisionErrorや、アサーションの失敗を表すAssertionErrorなど、さまざまな種類があります。 すべての例外クラスはBaseExceptionクラスから派生しています。開発者は組み込みの例外をそのまま利用できるだけでなく、raise文を使ってコード中で意図的に例外を発生させることもできます。さら