รับฟังก์ชั่นแทนที่ของคลาสย่อย


19

มีวิธีรับฟังก์ชั่น overriden ทั้งหมดของคลาสย่อยใน Python หรือไม่?

ตัวอย่าง:

class A:
    def a1(self):
        pass

    def a2(self):
        pass


class B(A):
    def a2(self):
        pass

    def b1(self):
        pass

นี่ฉันต้องการจะได้รับรายการ["a2"]สำหรับวัตถุของคลาสB(หรือสำหรับวัตถุชั้นเอง) ตั้งแต่ระดับแทนที่เพียงวิธีการเดียวคือBa2

คำตอบ:


18

คุณสามารถเข้าถึงคลาสแม่ด้วยcls.__bases__ค้นหาแอตทริบิวต์ทั้งหมดของผู้ปกครองด้วยdirและเข้าถึงคุณลักษณะทั้งหมดของคลาสเองด้วยvars:

def get_overridden_methods(cls):
    # collect all attributes inherited from parent classes
    parent_attrs = set()
    for base in cls.__bases__:
        parent_attrs.update(dir(base))

    # find all methods implemented in the class itself
    methods = {name for name, thing in vars(cls).items() if callable(thing)}

    # return the intersection of both
    return parent_attrs.intersection(methods)
>>> get_overridden_methods(B)
{'a2'}

varsเป็นสิ่งที่ฉันขาดหายไป ขอบคุณมากสำหรับคำตอบที่รวดเร็ว (เหลือเชื่อ)!
Andreas

parent_attrsในหนึ่งบรรทัดถ้าคุณต้องการ:parent_attrs = {a for b in cls.__bases__ for a in dir(b)}
wjandrea

3

คุณสามารถใช้ประโยชน์จากสิ่ง__mro__อันดับซึ่งเก็บลำดับการแก้ไขวิธีการ

สำหรับตัวอย่างของคุณ:

>>> B.__mro__
( <class '__main__.B'>, <class '__main__.A'>, <class 'object'>) 

ดังนั้นคุณสามารถวนลูปของ tuple นั้นและตรวจสอบว่าBเมธอดนั้นอยู่ในคลาสอื่นด้วยหรือไม่


นี้จะไม่ได้ยกเว้นที่กำหนดไว้ล่วงหน้าวิธีการเช่นใดDunder วิธี__init__, __eq__, ....... etc
Charif DZ

0
class A:

    def a1(self):
        pass

    def a2(self):
        pass


class B(A):

    def a2(self):
        super().a2()  
        pass

    def b1(self):
        pass
obj = B()

obj.a2()   # ***first give the output of parent class then child class***

1
ฉันคิดว่าคุณเข้าใจผิดคำถาม คลาสAและBไม่สามารถแก้ไขได้ OP ต้องการที่จะทราบว่าB's วิธีแทนที่หนึ่งA' s วิธี
wjandrea
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.