مفهومی که تو این پست درموردش حرف میزنیم، اینطوریه که یک کلاس به عنوان فرزند(child) یک کلاس دیگه به حساب میاد، بدون اینکه از کلاس والد(parent) به طور صریح ارثبری کرده باشه! چطوری؟ بریم ببینیم.
توی پایتون وقتی میخوایم ببنیم که یک کلاس از یک کلاس دیگه ارثبری داشته یا نه از متدی به اسم issubclass استفاده میکنیم، یعنی به این شکل:
class Parent: pass class Child(Parent): pass print(issubclass(Child, Parent)) # True
خب تا اینجای کار رفتار طبیعیه و چیز عجیب غریب نداریم.
اما ما میتونیم به کمک metaclass و بدون ارثبری مستقیم همین جواب رو بگیریم! کد زیر نمونهای از این ماجراست:
class Base(type): def __subclasscheck__(cls, subclass): return True class Parent(metaclass=Base) pass class Child: pass print(issubclass(Child, Parent)) # True
اگر با metaclass آشنا نیستید، میتونید از این مطلب کمک بگیرید:
یک مثال کاربردیترش رو میتونید اینجا ببنید.
اما این کار به روش دیگهای هم این کار ممکن میباشد، و تو این روش از __subclasshook__ استفاده میشه، به این قطعه کد توجه کنید:
from abc import ABC class Parent(ABC): def do_something(self): pass @classmethod def __subclasshook__(cls, C): if cls is Parent: for B in C.__mro__: if hasattr(B, 'do_something') return True return NotImplemented اگر دارین میگین که چه نامگذاری مزخرفی بله میدونم :) البته کد بالا رو میشه این طوری هم نوشت: if cls is Parent: if any("do_something" in B.__dict__ for B in C.__mro__): return True return NotImplemented class Child: def do_something(self): pass Parent.register(Child) print(issubclass(Child, Parent)) # True
همین!
به یاد عزیزان پروازهای PS752 و IR655
و به امید روزهای خوب.
منابع: