2013-04-23 42 views
8

在我寫的,我使用了我的Python項目記錄的目的元類。它使每個班級自動記錄所有活動。唯一的問題是,我不想去到每一個文件都在增加:的Python:設置所有文件的元類的文件夾

__metaclass__ = myMeta 

有沒有辦法設置在頂層文件夾中的元類,使所有使用在其下方元類文件?

+0

@slashdottir:你去了,回答更新到2.7。這又是一次黑客攻擊。 – 2016-03-03 21:10:15

回答

6

不行,你只能指定每個類或每個模塊的元類。您無法將其設置爲整個包裝。

在Python 3.1及以後,你可以攔截builtins.__build_class__鉤和編程插入一個元類,見Overriding the default type() metaclass before Python runs

在Python 2.7,你可以與使用你的元類的子類取代__builtins__.object。像builtins.__build_class__掛鉤,這是先進兩輪牛車並儘可能打破你的代碼,讓你在元類everwhere。導入你的包和所有新樣式類(那些可以支持元類)將有你的元類之前

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 

運行enable()這樣的:

通過在__builtin__ module更換object參考這樣做。請注意,此行爲現在將傳播到全部 Python代碼尚未加載,包括標準庫,因爲您的包導入了代碼。您可能想要使用:

enable() 
import package 
disable() 

限制效果。

+0

太棒了!我要去嘗試一下。謝謝! – slashdottir 2016-03-03 21:11:55

1

這是一個簡單的技術。只是子類本身具有__metaclass__屬性的子類。這個過程可以自動化。

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'))) 

測試;

$ python main.py 
type object 'A' has no attribute 'created' 
('Wed Mar 9 22:58:16 2016', 'Michael Jackson') 
相關問題