Python | メタクラスの使い方
公開日:2021/6/5
Pythonでは,クラスを使うことによってデータと機能を合わせて出力することができる.メタクラスは,クラス変数が適切に定義されているかをチェックするできる.以下にメタクラスの使い方を記す.
◆実施環境
Python 3.8.8
■メタクラスを利用した基本構文
メタクラスの定義方法として,"type"を継承させる方法がある.その後,"__new__"をインスタンスメソッドとして利用する.
# 1の処理
class Meta_test(type): # メタクラス
def __new__(metacls,cls_name,cls_bases,cls_attrs):
print(f'metacls:{metacls}') # metaclsはメタクラスのタイプと名前を出力
print(f'cls_name:{cls_name}') # cls_nameはクラスの名前を出力
print(f'cls_bases:{cls_bases}') # cls_basesは継承クラスを出力
print(f'cls_attrs:{cls_attrs}') # cls_attrsはクラスが持つ値や関数を出力
return super().__new__(metacls,cls_name,cls_bases,cls_attrs)
class Class1(metaclass=Meta_test):
z = '1234'
pass
■実行結果
# 1の結果
metacls:<class '__main__.Meta_test'>
cls_name:Class1
cls_bases:()
cls_attrs:{'__module__': '__main__', '__qualname__': 'Class1', 'z': '1234'}
■Exceptionを用いたクラスのチェック
“class 例外クラス(Exception):"によって例外を定義し,特定の変数がない場合にエラーを出力させることができる.以下はエラーが出力される構文と出力されない構文を作成した.
# 1の処理(特定の変数がない場合にエラーが出力)
class MetaExcept(Exception): # 例外を定義する
pass
class Meta_test(type): # メタクラス
def __new__(metacls,cls_name,cls_bases,cls_attrs):
print(f'metacls:{metacls}') # metaclsはメタクラスのタイプと名前を出力
print(f'cls_name:{cls_name}') # cls_nameはクラスの名前を出力
print(f'cls_bases:{cls_bases}') # cls_basesは継承クラスを出力
print(f'cls_attrs:{cls_attrs}') # cls_attrsはクラスが持つ値や関数を出力
if 'xyz' not in cls_attrs.keys():
raise MetaExcept('xyzを定義してください')
return super().__new__(metacls,cls_name,cls_bases,cls_attrs)
class Class1(metaclass=Meta_test):
z = '1234'
pass
# 2の処理(#1の処理を受け,特定の変数を記述:エラーなし)
class MetaExcept(Exception):
pass
class Meta_test(type): # メタクラス
def __new__(metacls,cls_name,cls_bases,cls_attrs):
print(f'metacls:{metacls}') # metaclsはメタクラスのタイプと名前を出力
print(f'cls_name:{cls_name}') # cls_nameはクラスの名前を出力
print(f'cls_bases:{cls_bases}') # cls_basesは継承クラスを出力
print(f'cls_attrs:{cls_attrs}') # cls_attrsはクラスが持つ値や関数を出力
if 'xyz' not in cls_attrs.keys():
raise MetaExcept('xyzを定義してください')
return super().__new__(metacls,cls_name,cls_bases,cls_attrs)
class Class1(metaclass=Meta_test):
z = '1234'
xyz = 'ABCD'
pass
■実行結果
# 1の結果(エラーが出力)
metacls:<class '__main__.Meta_test'>
cls_name:Class1
cls_bases:()
cls_attrs:{'__module__': '__main__', '__qualname__': 'Class1', 'z': '1234'}
__main__.MetaExcept: xyzを定義してください
# 2の結果(エラーが出力されず,'xyz'がcls_attrsに含まれる)
metacls:<class '__main__.Meta_test'>
cls_name:Class1
cls_bases:()
cls_attrs:{'__module__': '__main__', '__qualname__': 'Class1', 'z': '1234', 'xyz': 'ABCD'}
以上