2009-03-06 35 views
6

Tôi đã hack lớp trong Python như thế này:Python metaclasses

def hack(f,aClass) : 
    class MyClass(aClass) : 
    def f(self) : 
     f() 
    return MyClass 

A = hack(afunc,A) 

nào trông khá sạch sẽ với tôi. Phải mất một lớp, A, tạo ra một lớp mới bắt nguồn từ nó có một phương thức bổ sung, gọi f, và sau đó gán lại lớp mới cho A.

Điều này khác với việc hack bằng metaclass bằng Python như thế nào? Lợi thế của việc sử dụng một số điện thoại metaclass là gì?

+0

Lý do để thực hiện việc này là gì? –

Trả lời

5

Định nghĩa của một lớp trong Python là một thể hiện kiểu (hoặc một thể hiện của một lớp con của kiểu). Nói cách khác, định nghĩa lớp chính nó là một đối tượng. Với metaclasses, bạn có khả năng kiểm soát thể hiện kiểu trở thành định nghĩa lớp.

Khi metaclass được gọi, bạn có khả năng viết lại hoàn toàn định nghĩa lớp. Bạn có quyền truy cập vào tất cả các thuộc tính được đề xuất của lớp, tổ tiên của nó, v.v. Không chỉ tiêm một phương thức hoặc loại bỏ một phương thức, bạn có thể thay đổi triệt để cây thừa kế, kiểu và nhiều khía cạnh khác. Bạn cũng có thể chuỗi các metaclasses với nhau cho một trải nghiệm rất năng động và hoàn toàn phức tạp.

Tôi cho rằng lợi ích thực sự, mặc dù là loại của lớp vẫn là loại của lớp. Trong ví dụ của bạn, nhập:

a_inst = A() 
type(a_inst) 

sẽ cho biết rằng đó là phiên bản MyClass. Có, isinstance(a_inst, aClass) sẽ trả lại True, nhưng bạn đã giới thiệu một lớp con, thay vì một lớp được xác định lại động. Sự khác biệt có lẽ là chìa khóa.

Như rjh chỉ ra, lớp bên trong vô danh cũng có ý nghĩa về hiệu suất và khả năng mở rộng. Một metaclass được xử lý chỉ một lần, và thời điểm mà lớp được xác định, và không bao giờ một lần nữa. Người dùng API của bạn cũng có thể mở rộng metaclass của bạn bởi vì nó không được đính kèm trong một hàm, do đó bạn có được một mức độ mở rộng nhất định.

bài viết hơi cũ này thực sự có một lời giải thích tốt mà so sánh chính xác phương pháp "chức năng trang trí" mà bạn sử dụng trong ví dụ với metaclasses, và cho thấy lịch sử của Python metaclass tiến hóa trong bối cảnh đó: http://www.ibm.com/developerworks/linux/library/l-pymeta.html

1

Bạn cũng có thể sử dụng số điện thoại type.

def hack(f, aClass): 
    newfunc = lambda self: f() 
    return type('MyClass', (aClass,), {'f': newfunc}) 

Tôi tìm cách sử dụng type cách dễ nhất để vào thế giới metaclass.

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