概要
pythonでクラスメソッドのオーバーライドを禁止したかったのですが、検索してもヒットしなかったので将来の自分のために書き残します。
※追記
@shiracamus さんからコメントで有益な情報をいただきました。
そちらのクラスを実装するのが現状の最適解かと思われます。
※追記(19/2/4)
あくまで実行前の処理になりますが、mypyのFinal methodsを使う手もありそうです。
https://mypy.readthedocs.io/en/latest/final_attrs.html#final-methods
結論
class OverrideException(Exception):
def __init__(self, method_name: str) -> None:
super().__init__()
self.method_name = method_name
def message(self) -> str:
return f'"{self.method_name}" method is can not be overwritten.'
class Parent:
def __init__(self) -> None:
not_override_methods = [
'override_method'
]
if self.__class__.__name__ != "Parent":
for mtd in not_override_methods:
if mtd in self.__class__.__dict__:
raise OverrideException(mtd)
def override_method(self) -> None:
print("上書きしちゃダメよ")
class Child_1(Parent):
def __init__(self) -> None:
super().__init__()
def override_method(self) -> None:
print("しちゃった")
try:
# オーバーライドしてるとエラー
Child_1()
except OverrideException as e:
print("Child_1: ", end="")
print(e.message())
# 以下補足 =========================
class Child_2(Parent):
def __init__(self) -> None:
super().__init__()
try:
# オーバーライドしてなければ問題なし
Child_2()
except OverrideException as e:
print("Child_2: ", end="")
print(e.message())
try:
# 親そのものを呼び出しても問題なし
Parent()
except OverrideException as e:
print("Parent側: ", end="")
print(e.message())
補足
標準ライブラリ、標準関数とかに入っていたりしないんだろうか。