2013-04-23 44 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') 
相关问题