2013-04-23 12 views
8

Pythonプロジェクトでロギング目的で使用しているメタクラスを書きました。すべてのクラスがすべてのアクティビティを自動的にログに記録します。唯一の問題は、私はすべてのファイルに移動して、を追加する必要がありますする必要はないということです:ようにトップレベルのフォルダ内のメタクラスを設定する方法はありPython:フォルダ内のすべてのファイルのメタクラスを設定する

__metaclass__ = myMeta 

メタクラスの使用下にあるすべてのファイル?

+0

@slashdottir:あなたが行って、答えを2.7に更新しました。それはもう一つのハックです。 –

答えて

6

いいえ、クラス単位またはモジュール単位でのみメタクラスを指定できます。パッケージ全体に設定することはできません。 builtins.__build_class__フックインターセプト

のPython 3.1では以降、あなたはできOverriding the default type() metaclass before Python runsを参照して、プログラム的メタクラスを挿入します。

Python 2.7では、__builtins__.objectをメタクラスを使用するサブクラスに置き換えることができます。 builtins.__build_class__フックのように、これは高度なハッカーであり、永遠にメタクラスを取得するのと同じくらいコードを壊します。

__builtin__ moduleobject参照を置き換えることによってそう:

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()これはあなたのパッケージとすべての新しいスタイルのクラス(メタクラスをサポートすることができるもの)をインポートする前に、あなたのメタクラスを持つことになります。この動作はにすべて反映されることに注意してください。パッケージがコードをインポートする際に、標準ライブラリを含むPythonコードがまだロードされていません。あなたはおそらく:

enable() 
import package 
disable() 

効果を制限します。

+0

すごい!私はそれを試してみるつもりです。ありがとうございました! – slashdottir

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') 
関連する問題