2012-05-08 32 views
5

Theo tài liệu, object là tất cả lớp cơ sở của lớp mới.Lớp cơ sở kiểu mới của Python - `đối tượng` và` loại`

Và AFAIK, các lớp được gọi là kiểu mới chỉ là những lớp có thể có được một số mẫu mới bằng cách kế thừa object, phải không?

Tôi nghĩ object kế thừa type hoặc sử dụng type như __metaclass__ của nó, nhưng object.__bases__ mang lại cho tôi không có gì, vì vậy mà liều object này đến từ đâu, và mối quan hệ bewteen nó và type là gì?

Trả lời

5

Thật vậy, loại (tức là, Metaclass) của object, một lớp, là type:

type(object) == type  # True 

Và kể từ object là lớp cơ sở, nó không có cha mẹ của riêng nó, như bạn mong muốn:

object.__bases__ ==() # True 

object doesn Không có thuộc tính __metaclass__ vì nó không cần thuộc tính: nó sử dụng metaclass mặc định, type.

Bây giờ đó là một chút bối rối vì type là trong thực tế, một lớp con của object, mà lởn vởn trong đầu (làm thế nào có thể type được bắt nguồn từ object khi bạn cần type để xây dựngobject?) Nhưng điều này được giải quyết bằng một ít khó khăn -coding ở mức C trong trình thông dịch Python.

Tất cả điều này chỉ áp dụng cho các lớp học theo phong cách mới, có nghĩa là các lớp học có nguồn gốc từ object. Trong Python 3, tất cả các lớp là kiểu mới, do đó, điều này áp dụng trên toàn cầu bằng Python 3.

+1

sử dụng metaclass mặc định? Bạn có nghĩa là, nếu tôi xác định một lớp (không kế thừa 'đối tượng') mà không chỉ định metaclass của nó, thì lớp này sẽ được hiểu bởi' type'? – Alcott

+1

Vâng, vâng, tôi nghĩ vậy. – Alcott

+1

Có. 'type' là metaclass Python sử dụng nếu bạn không chỉ định metaclass. – kindall

3

Có hai khái niệm đó có thể là hữu ích cần lưu ý:

  • mọi thứ trong python là một đối tượng, bao gồm các lớp học và metaclasses
  • metaclasses là các nhà thầu của các lớp học, chứ không phải tổ tiên của họ, vì vậy họ không xuất hiện trong __bases__.

Điều đó có nghĩa là object thực sự có type làm metaclass.

Cũng giống như một sự tò mò, phần "nghịch lý" của câu chuyện là type, mà là một metaclass cũng là một đối tượng, nhưng không thể có chính nó như metaclass (nó sẽ là một chút của gà và trứng vấn đề, nếu bạn nghĩ về nó).

Nghịch lý được giải quyết với một số voodoo C trong mã nguồn python, nhưng tôi không biết nhiều về nó!

EDIT: (một số mã ví dụ)

>>> class MyMeta(type): 
...  def __new__(cls, name, bases, dct): 
...   return type.__new__(cls, name, bases, dct) 
... 
>>> class MyClass(object): 
...  __metaclass__ = MyMeta 
... 

Bây giờ quan sát rằng obj kế thừa từ object

>>> obj = MyClass() 
>>> MyClass.__bases__ 
(<type 'object'>,) 

Đối với câu hỏi của bạn trong các ý kiến ​​về dir(obj) không sản lượng __metaclass__ thuộc tính : lý do là __metaclass__ là thuộc tính của lớp không phải đối tượng được khởi tạo của nó. Lưu ý trong thực tế là: (! Với một câu trả lời rất toàn diện, tất nhiên)

>>> dir(MyClass) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 
>>> MyClass.__metaclass__ 
<class '__main__.MyMeta'> 

Nếu bạn quan tâm đến đào sâu hiểu biết của bạn metaclasses, đây là một cổ điển SO câu hỏi:

What is a metaclass in Python?

HTH!

+0

Vâng, tôi thực sự nghĩ rằng 'type' là 'metaclass object', nhưng' dir (object)' thậm chí không có một thuộc tính là '__metaclass__' , tại sao? – Alcott

+1

Vì 'loại' được sử dụng theo mặc định. '__metaclass__' có thể được sử dụng để ghi đè lên nó. – yak

+0

Cảm ơn các ví dụ mã chi tiết. – Alcott

2

Bạn có thể tìm thấy thisthis bài đăng thú vị. Dưới đây là sơ đồ từ đầu tiên:

enter image description here

+0

Vâng, 'đối tượng' là cơ sở của' loại'? – Alcott

+0

@Alcott: vâng, đúng vậy. Và 'type' là kiểu' đối tượng'. Đọc các bài viết được liên kết và các bài viết có liên quan khác từ blog để có giải thích sâu hơn –

Các vấn đề liên quan