2013-04-23 29 views
8

Tôi đã viết một metaclass mà tôi đang sử dụng cho mục đích ghi nhật ký trong dự án python của tôi. Nó làm cho mọi lớp tự động đăng nhập tất cả các hoạt động. Vấn đề duy nhất là tôi không muốn đi vào tất cả các file và phải thêm vào:Python: Đặt metaclass cho tất cả các tệp trong một thư mục

__metaclass__ = myMeta 

Có cách nào để thiết lập các metaclass trong thư mục cấp cao nhất để tất cả các file bên dưới sử dụng mà metaclass ?

+0

@slashdottir: có bạn đi, trả lời cập nhật để trang trải 2.7. Đó là một hack khác. –

Trả lời

6

Không, bạn chỉ có thể chỉ định metaclass cho mỗi lớp hoặc mỗi mô-đun. Bạn không thể đặt nó cho toàn bộ gói.

Trong Python 3.1 trở lên, bạn có thể chặn móc builtins.__build_class__ và chèn một metaclass theo chương trình, xem Overriding the default type() metaclass before Python runs.

Trong Python 2.7, bạn có thể thay thế __builtins__.object bằng một lớp con sử dụng metaclass của bạn. Giống như móc builtins.__build_class__, đây là hack tiên tiến và ngắt mã của bạn nhiều như nhận được metaclass của bạn ở mọi nơi.

Làm như vậy bằng cách thay thế object tham chiếu trên __builtin__ module:

import __builtin__ 


class MetaClass(type): 
    def __new__(mcls, name, *args): 
     # do something in the metaclass 
     return super(MetaClass, mcls).__new__(mcls, name, *args) 


orig_object = __builtin__.orig_object 


class metaobject(orig_object): 
    __metaclass__ = MetaClass 


def enable(): 
    # *replace* object with one that uses your metaclass 
    __builtin__.object = metaobject 

def disable(): 
    __builtin__.object = orig_object 

Run enable() này trước khi nhập gói của bạn và tất cả các lớp học kiểu mới (những người mà thể hỗ trợ một metaclass) sẽ có metaclass của bạn. Lưu ý rằng hành vi này hiện sẽ lan truyền đến tất cả Mã Python chưa được tải, bao gồm thư viện chuẩn, như mã nhập gói của bạn. Bạn có thể muốn sử dụng:

enable() 
import package 
disable() 

để giới hạn hiệu ứng.

+0

tuyệt vời! Tôi sẽ thử nó. cảm ơn bạn! – slashdottir

1

Đây là một kỹ thuật đơn giản. Chỉ cần lớp con các lớp chính nó với thuộc tính __metaclass__ trong lớp con. Quá trình này có thể được tự động hóa.

util.py

class A(object): 
    def __init__(self, first, second): 
     self.first = first 
     self.second = second 

    def __str__(self): 
     return '{} {}'.format(self.first, self.second) 

main.py

from datetime import datetime 
from util import A 

def meta(*args): 
    cls = type(*args) 
    setattr(cls, 'created', datetime.now().ctime()) 
    return cls 

try: 
    print(A.created) 
except AttributeError as e: 
    print(e) 

class A(A): 
    __metaclass__ = meta 

print(A.created, str(A('Michael', 'Jackson'))) 

thử nghiệm;

$ python main.py 
type object 'A' has no attribute 'created' 
('Wed Mar 9 22:58:16 2016', 'Michael Jackson') 
Các vấn đề liên quan