Làm thế nào để có được cha mẹ của một lớp Python?


202

Làm cách nào tôi có thể nhận được lớp cha của lớp Python?

Câu trả lời:


233

Sử dụng thuộc tính sau:

cls.__bases__

Từ các tài liệu :

Bộ dữ liệu của các lớp cơ sở của một đối tượng lớp.

Thí dụ:

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

Một vi dụ khac:

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

1
Để có được căn cứ của một đối tượng được khởi tạo, hãy làm type(C()).__bases__như được đề cập thêm bên dưới
citynorman

106

Nếu bạn muốn tất cả các tổ tiên chứ không chỉ là những người ngay lập tức, hãy sử dụng tests.getmro :

import inspect
print inspect.getmro(cls)

Sử dụng, điều này cung cấp cho bạn tất cả các lớp tổ tiên theo "thứ tự phân giải phương thức" - tức là thứ tự mà tổ tiên sẽ được kiểm tra khi phân giải một phương thức (hoặc, thực tế, bất kỳ thuộc tính nào khác - các phương thức và các thuộc tính khác sống trong cùng một không gian tên trong Python, sau tất cả ;-).


34
Bạn cũng có thể chỉ cần sử dụng cls.__mro__(ít nhất là trong Python 3.5)
naught101

@ naught101, làm ơn biến nó thành một câu trả lời đầy đủ. Tôi gần như đã bỏ lỡ nó, và tôi cũng sẽ nghĩ như vậy.
Shihab Shahriar Khan

14

Các lớp kiểu mới có một phương thức mro mà bạn có thể gọi, nó trả về một danh sách các lớp cha theo thứ tự độ phân giải phương thức.


Những gì được coi là một lớp phong cách mới? Có vẻ như tôi có thể sử dụng điều này với các mô hình Django, nhưng mọi thứ chỉ đơn giản là thừa hưởng từ objectdường như không đáp ứng mro.
Brian Kung

1
xem xét một đối tượng x, chúng ta có thể nhận được thứ tự giải quyết phương thức với lệnh gọi type(x).mro() mà chúng ta có thể xem xét nếu xClassXnhư một lớp cơ sở với: ClassX in type(x).mro()
648trindade

13

Cách NHANH NHẤT , để xem tất cả các bậc cha mẹ và ĐẶT HÀNG , chỉ cần sử dụng tích hợp__mro__

I E repr(YOUR_CLASS.__mro__)


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

kết quả đầu ra, TRÊN TRÌNH TỰ


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

Có bạn có nó. Câu trả lời "tốt nhất" ngay bây giờ, có 182 phiếu bầu (như tôi đang gõ này) nhưng điều này đơn giản hơn nhiều so với một số vòng lặp, nhìn vào các cơ sở một lớp tại một thời điểm, chưa kể khi một lớp mở rộng HAI hoặc nhiều phụ huynh các lớp học. Nhập và sử dụng inspectchỉ đám mây phạm vi không cần thiết. Thật sự là một sự xấu hổ mà mọi người không biết chỉ sử dụng các công cụ tích hợp

Tôi hi vọng cái này giúp được!


@John Smith stackoverflow.com/users/139885/john-smith , tôi hy vọng bạn thấy câu trả lời này. Nếu bạn thích nó, xin vui lòng cho tôi biết với một upvote!
PyTis

1
Trong thực tế, inspect.getmrochỉ cần gọi __mro__vào đối tượng, như bạn có thể thấy trong github.com/python/cpython/blob/ mẹo . Sử dụng getmrosản xuất mã sạch hơn và dễ đọc hơn. Mặc dù bỏ qua một cuộc gọi chức năng thực sự nhanh hơn.
tna0y

9

Sử dụng các cơ sở nếu bạn chỉ muốn lấy cha mẹ, sử dụng __mro__(như được chỉ ra bởi @ naught101) để nhận thứ tự giải quyết phương thức (để biết thứ tự của init được thực thi theo thứ tự nào).

Căn cứ (và đầu tiên nhận lớp cho một đối tượng hiện có):

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

Đối với mro trong các phiên bản Python gần đây:

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

Rõ ràng, khi bạn đã có một định nghĩa lớp, bạn chỉ có thể gọi __mro__trực tiếp vào đó:

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

3

Nếu bạn muốn đảm bảo tất cả chúng đều được gọi, hãy sử dụng superở tất cả các cấp.


Một khi bạn sử dụng siêu, bạn phải sử dụng nó ở tất cả các cấp độ, đó là lý do tại sao bạn nên sử dụng tài liệu một cách rõ ràng. Ngoài ra, bạn có thể muốn biết rằng siêu không hoạt động trên mỗi lớp ...
DasIch
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.