วิธีรับพาเรนต์ของคลาส Python


คำตอบ:


233

ใช้คุณลักษณะต่อไปนี้:

cls.__bases__

จากเอกสาร :

tuple ของคลาสพื้นฐานของคลาสอ็อบเจ็กต์

ตัวอย่าง:

>>> str.__bases__
(<type 'basestring'>,)

ตัวอย่างอื่น:

>>> class A(object):
...   pass
... 
>>> class B(object):
...   pass
... 
>>> class C(A, B):
...   pass
... 
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)

1
หากต้องการรับฐานของวัตถุที่สร้างอินสแตนซ์ให้ทำtype(C()).__bases__ตามที่กล่าวไว้ด้านล่าง
citynorman

106

หากคุณต้องการบรรพบุรุษทั้งหมดไม่ใช่แค่คนใกล้ตัวใช้inspect.getmro :

import inspect
print inspect.getmro(cls)

มีประโยชน์สิ่งนี้จะให้คลาสบรรพบุรุษทั้งหมดใน "ลำดับการแก้ไขเมธอด" - นั่นคือลำดับที่บรรพบุรุษจะถูกตรวจสอบเมื่อทำการแก้ไขเมธอด (หรือที่จริงแล้วแอ็ตทริบิวต์อื่น ๆ - เมธอดและแอตทริบิวต์อื่น ๆ ใน Python หลังจากทั้งหมด ;-)


34
คุณสามารถใช้cls.__mro__(อย่างน้อยใน Python 3.5)
naught101

@ naught101, plz เปลี่ยนเป็นคำตอบแบบเต็ม ฉันเกือบจะพลาดไปแล้วฉันจะคิดถึงคนอื่นมากมาย
Shihab Shahriar Khan

14

คลาสสไตล์ใหม่มีเมธอด mro ซึ่งคุณสามารถเรียกใช้ซึ่งส่งคืนรายการของคลาสพาเรนต์ตามลำดับการแก้ไขเมธอด


สิ่งที่นับเป็นชั้นเรียนรูปแบบใหม่? ดูเหมือนว่าฉันสามารถใช้กับรุ่น Django แต่สิ่งที่สืบทอดจากเพียงแค่ดูเหมือนจะไม่ตอบสนองต่อการobject mro
Brian Kung

1
เมื่อพิจารณาถึงอ็อบเจกต์xเราสามารถรับลำดับการแก้ไขเมธอดด้วยการเรียกที่ type(x).mro() เราสามารถพิจารณาxได้ClassXว่าเป็นคลาสพื้นฐานที่มี: ClassX in type(x).mro()
648trindade

13

เร็วที่สุดวิธีเพื่อที่จะเห็นพ่อแม่ทุกคนและในการสั่งซื้อเพียงแค่ใช้ในการสร้าง__mro__

กล่าวคือ repr(YOUR_CLASS.__mro__)


>>>
>>>
>>> import getpass
>>> getpass.GetPassWarning.__mro__

เอาท์พุทในการสั่งซื้อ


(<class 'getpass.GetPassWarning'>, <type 'exceptions.UserWarning'>,
<type 'exceptions.Warning'>, <type 'exceptions.Exception'>, 
<type 'exceptions.BaseException'>, <type 'object'>)
>>>

ที่นั่นคุณมีมัน คำตอบที่ "ดีที่สุด" ตอนนี้มี 182 คะแนน (ขณะที่ฉันกำลังพิมพ์) แต่นี่ง่ายกว่าบางอย่างที่ซับซ้อนสำหรับการวนดูในฐานหนึ่งชั้นในเวลาไม่พูดถึงเมื่อชั้นขยายสองหรือมากกว่าผู้ปกครอง ชั้นเรียน การนำเข้าและใช้งานinspectเพียงแค่สร้างความสับสนให้กับขอบเขตเท่านั้น จริงๆแล้วมันเป็นความอัปยศที่ผู้คนไม่รู้ว่าจะใช้ตัวบิวด์อิน

ฉันหวังว่านี่จะช่วยได้!


@John Smith stackoverflow.com/users/139885/john-smithฉันหวังว่าคุณจะเห็นคำตอบนี้ หากคุณชอบโปรดแจ้งให้เราทราบด้วยการอัปโหลด!
PyTis

1
ในความเป็นจริงinspect.getmroเพียงแค่เรียก__mro__บนวัตถุที่คุณสามารถเห็นในgithub.com/python/cpython/blob/... การใช้ getmroสร้างโค้ดที่สะอาดและอ่านง่ายขึ้น แม้ว่าการข้ามการเรียกฟังก์ชันจะเร็วขึ้นแน่นอน
tna0y

9

ใช้เบสถ้าคุณต้องการให้ผู้ปกครองใช้__mro__(ตามที่ระบุโดย @ naught101) สำหรับการรับลำดับการแก้ไขเมธอด

ฐาน (และรับคลาสสำหรับวัตถุที่มีอยู่ก่อน):

>>> some_object = "some_text"
>>> some_object.__class__.__bases__
(object,)

สำหรับ mro ในเวอร์ชัน Python ล่าสุด:

>>> some_object = "some_text"
>>> some_object.__class__.__mro__
(str, object)

เห็นได้ชัดว่าเมื่อคุณมีคำจำกัดความของคลาสแล้วคุณสามารถโทรหา__mro__ได้โดยตรงที่:

>>> class A(): pass
>>> A.__mro__
(__main__.A, object)

3

หากคุณต้องการให้แน่ใจว่าพวกเขาทั้งหมดถูกเรียกใช้superในทุกระดับ


เมื่อคุณใช้ super คุณจะต้องใช้มันในทุกระดับอยู่แล้วซึ่งเป็นเหตุผลว่าทำไมคุณควรจัดทำเอกสารมันใช้อย่างชัดเจน นอกจากนี้คุณอาจต้องการทราบว่าซุปเปอร์ไม่สามารถใช้ได้กับทุกชั้นเรียน
DasIch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.