2011-10-31 24 views
5

Sau khi đọc tuyệt vời SO post, tôi đã cố gắng crafting một metaclass cấp module:Python metaclass và cơ sở đối tượng lớp

def metaclass(future_class_name, future_class_parents, future_class_attrs): 
    print "module.__metaclass__" 
    future_class_attrs["bar"]="bar" 
    return type(future_class_name, future_class_parents, future_class_attrs) 

__metaclass__=metaclass 


class Foo(object): 

    def __init__(self): 
     print 'Foo.__init__' 

f=Foo() 

này không hoạt động (ví dụ "môđun metaclass" không được in) trừ khi tôi xóa lớp cơ sở object của Foo. Làm thế nào mà?

LƯU Ý: Tôi đang sử dụng Python 2.6.1.

Trả lời

3

Kế thừa từ đối tượng tự động mang đến loại metaclass cùng với nó. Điều này ghi đè mô-đun cấp độ __metaclass__ mô-đun của bạn.

Nếu metaclass được quy định ở cấp lớp, sau đó đối tượng sẽ không ghi đè lên nó:

def metaclass(future_class_name, future_class_parents, future_class_attrs): 
    print "module.__metaclass__" 
    future_class_attrs["bar"]="bar" 
    return type(future_class_name, future_class_parents, future_class_attrs) 

class Foo(object): 
    __metaclass__ = metaclass 

    def __init__(self): 
     print 'Foo.__init__' 

f=Foo() 

Xem http://docs.python.org/reference/datamodel.html?highlight=metaclass#customizing-class-creation

+0

Đặc điểm kỹ thuật không nói gì như vậy. Những gì nó nói là nếu có một baseclass, metaclass của baseclass sẽ được sử dụng, bất kể có hay không baseclass chỉ định một metaclass. – Marcin

2

Các đặc điểm kỹ thuật specifies the order in which Python will look for a metaclass:

Các metaclass thích hợp được xác định bởi các ưu tiên sau đây quy tắc:

  • Nếu tồn tại dict['__metaclass__'], nó được sử dụng.
  • Nếu không, nếu có tại ít nhất một lớp cơ sở, metaclass của nó được sử dụng (điều này sẽ tìm một thuộc tính __class__ trước và nếu không tìm thấy, sử dụng loại của nó).
  • Nếu không, nếu biến toàn cục có tên là __metaclass__ tồn tại, nó sẽ được sử dụng.
  • Nếu không, kiểu cũ, cổ điển metaclass (types.ClassType) được sử dụng.

Bạn sẽ nhìn thấy từ trên đó có một lớp cơ sở ở tất cả (bất kể các lớp cơ sở là, ngay cả khi nó không cuối cùng kế thừa từ object) trước empts các mô-đun cấp __metaclass__.

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