Liệt kê tất cả các lớp cơ sở trong một hệ thống phân cấp của lớp đã cho?


Câu trả lời:


196

inspect.getmro(cls)hoạt động cho cả các lớp kiểu mới và kiểu cũ và trả về giống như NewClass.mro(): một danh sách lớp và tất cả các lớp tổ tiên của nó, theo thứ tự được sử dụng để phân giải phương thức.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)

2
Không hoạt động đối với các lớp pyobjc :( Tệp "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", dòng 70, trong bản in ép kiểm tra.getmro (đường dẫn) Tệp "/System/L Library / Frameworks / Python.fram Các phiên bản / 2.7 / lib / python2.7 / notify.py ", dòng 348, trong các tìm kiếm getmro (cls, kết quả) Tệp" /System/L Library / Frameworks / Python.framework / Warions / 2.7 / lib / python2.7 / inspect py", dòng 339, trong _searchbases cho cơ sở trong cls .__ bases_ : AttributeError: ' đối tượng NSTaggedDate' không có thuộc tính '__bases '
RBP

17
@rbp Tôi nghi ngờ rằng bạn có cùng một vấn đề mà tôi gặp phải: bạn đang cố gắng làm inspect.getmro(obj)thay vì inspect.getmro(type(obj)).
chấp nhận

44

Xem thuộc __bases__tính có sẵn trên một con trăn class, trong đó có một bộ các lớp cơ sở:

>>> def classlookup(cls):
...     c = list(cls.__bases__)
...     for base in c:
...         c.extend(classlookup(base))
...     return c
...
>>> class A: pass
...
>>> class B(A): pass
...
>>> class C(object, B): pass
...
>>> classlookup(C)
[<type 'object'>, <class __main__.B at 0x00AB7300>, <class __main__.A at 0x00A6D630>]

5
Điều này có thể giới thiệu trùng lặp. Và đây là lý do tại sao tài liệu getmronói rõ ràng "Không có lớp nào xuất hiện nhiều hơn một lần trong bộ dữ liệu này"?
Sridhar Ratnakumar

10
Thận trọng, __bases__chỉ đi lên một cấp . (Như tiện ích đệ quy của bạn ngụ ý, nhưng một cái nhìn lướt qua ví dụ có thể không nhận ra điều đó.)
Bob Stein

32

inspect.getclasstree()sẽ tạo ra một danh sách các lớp và các căn cứ của chúng. Sử dụng:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.

1
Ooh tuyệt đó. Và để đầu ra đẹp hơn, hãy sử dụng pprint! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
chim cánh cụt359

20

bạn có thể sử dụng __bases__bộ dữ liệu của đối tượng lớp:

class A(object, B, C):
    def __init__(self):
       pass
print A.__bases__

Các tuple trả về __bases__có tất cả các lớp cơ sở của nó.

Hy vọng nó giúp!


Nếu lớp của bạn kế thừa từ một lớp kế thừa từ một lớp, chỉ có phần đầu tiên của chuỗi sẽ nằm trong lớp của nó__bases__
Boris

Đơn giản và sạch sẽ mà không cần nhập toàn bộ mô-đun cho một chức năng.
Temperosa

8

Trong python 3.7 bạn không cần nhập kiểm tra, type.mro sẽ cho bạn kết quả.

>>> class A:
...   pass
... 
>>> class B(A):
...   pass
... 
>>> type.mro(B)
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>>

chú ý rằng trong python 3.x mỗi lớp kế thừa từ lớp đối tượng cơ sở.


8

Theo tài liệu Python , chúng ta cũng có thể chỉ cần sử dụng class.__mro__thuộc tính hoặc class.mro()phương thức:

>>> class A:
...     pass
... 
>>> class B(A):
...     pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> object.__mro__
(<class 'object'>,)
>>>
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> A.mro()
[<class '__main__.A'>, <class 'object'>]
>>> object.mro()
[<class 'object'>]
>>> A in B.mro()
True

2

Mặc dù câu trả lời của Jochen rất hữu ích và chính xác, vì bạn có thể có được hệ thống phân cấp lớp bằng cách sử dụng phương thức .getmro () của mô-đun kiểm tra, điều quan trọng là làm nổi bật hệ thống phân cấp thừa kế của Python như sau:

Ví dụ:

class MyClass(YourClass):

Một lớp kế thừa

  • Lớp học trẻ em
  • Lớp có nguồn gốc
  • Phân lớp

Ví dụ:

class YourClass(Object):

Một lớp kế thừa

  • Lớp phụ huynh
  • Lớp cơ sở
  • Siêu lớp

Một lớp có thể kế thừa từ lớp khác - Lớp được gán là được kế thừa - đặc biệt, các phương thức của nó được kế thừa - điều này có nghĩa là các thể hiện của lớp (con) kế thừa có thể truy cập được quy cho lớp (cha) được kế thừa

dụ -> lớp -> sau đó các lớp kế thừa

sử dụng

import inspect
inspect.getmro(MyClass)

sẽ cho bạn thấy hệ thống phân cấp, trong Python.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.