在我寫的,我使用了我的Python項目記錄的目的元類。它使每個班級自動記錄所有活動。唯一的問題是,我不想去到每一個文件都在增加:的Python:設置所有文件的元類的文件夾
__metaclass__ = myMeta
有沒有辦法設置在頂層文件夾中的元類,使所有使用在其下方元類文件?
在我寫的,我使用了我的Python項目記錄的目的元類。它使每個班級自動記錄所有活動。唯一的問題是,我不想去到每一個文件都在增加:的Python:設置所有文件的元類的文件夾
__metaclass__ = myMeta
有沒有辦法設置在頂層文件夾中的元類,使所有使用在其下方元類文件?
不行,你只能指定每個類或每個模塊的元類。您無法將其設置爲整個包裝。
在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()
限制效果。
太棒了!我要去嘗試一下。謝謝! – slashdottir 2016-03-03 21:11:55
這是一個簡單的技術。只是子類類本身具有__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')
@slashdottir:你去了,回答更新到2.7。這又是一次黑客攻擊。 – 2016-03-03 21:10:15