Để bắt mắt của bạn:Có thể gọi metaclass có thể gọi được không?
Tôi nghĩ tài liệu có thể sai!
Theo tài liệu Python 2.7.12, 3.4.3. Tuỳ chỉnh lớp creation¶:
__metaclass__
biến này có thể là bất kỳ callable chấp nhận đối số cho tên, căn cứ, và dict. Khi tạo lớp học, số điện thoại có thể gọi được thay vì được xây dựng trongtype()
.Tính năng mới trong phiên bản 2.2.
Tuy nhiên, this article lập luận:
Q: Wow! Tôi có thể sử dụng bất kỳ đối tượng kiểu nào làm
__metaclass__
không?A: Không. Nó phải là lớp con của loại đối tượng cơ sở. ...
Vì vậy, tôi đã làm một thí nghiệm trên của riêng tôi:
class metacls(list): # <--- subclassing list, rather than type
def __new__(mcs, name, bases, dict):
dict['foo'] = 'metacls was here'
return type.__new__(mcs, name, bases, dict)
class cls(object):
__metaclass__ = metacls
pass
này mang lại cho tôi:
Traceback (most recent call last):
File "test.py", line 6, in <module>
class cls(object):
File "test.py", line 4, in __new__
return type.__new__(mcs, name, bases, dict)
TypeError: Error when calling the metaclass bases
type.__new__(metacls): metacls is not a subtype of type
Vì vậy, là tài liệu thực sự xảy ra?
"bị ràng buộc" có nghĩa là "một phân lớp", phải không? –
@sunqingyao: không, 'ràng buộc' có nghĩa là được gán cho. Phép gán 'Foo = []' được thực hiện. Câu lệnh 'class' về cơ bản được coi là một hàm; cơ thể được thực hiện như thể trong một hàm, và tất cả các tên địa phương được trích xuất thành một từ điển. Sau đó, đối tượng lớp được tạo ra bằng cách gọi 'bodydict.get ('__ metaclass__', type)' (do đó, hoặc là giá trị '__metaclass__' hoặc, nếu thiếu,' type') và chuyển tên lớp, căn cứ lớp và từ điển cơ thể. * Bất cứ điều gì được trả về * được gán cho tên của lớp. Ràng buộc là thuật ngữ kỹ thuật; những thứ khác cũng ràng buộc, như 'import' hoặc' for'. –
Nhưng bằng cách nói "' mcs' bị ràng buộc với 'danh sách'", bạn có nghĩa là "' mcs' là một thể hiện của một phân lớp của 'danh sách'". –