Pythonプロジェクトでロギング目的で使用しているメタクラスを書きました。すべてのクラスがすべてのアクティビティを自動的にログに記録します。唯一の問題は、私はすべてのファイルに移動して、を追加する必要がありますする必要はないということです:ようにトップレベルのフォルダ内のメタクラスを設定する方法はありPython:フォルダ内のすべてのファイルのメタクラスを設定する
__metaclass__ = myMeta
メタクラスの使用下にあるすべてのファイル?
Pythonプロジェクトでロギング目的で使用しているメタクラスを書きました。すべてのクラスがすべてのアクティビティを自動的にログに記録します。唯一の問題は、私はすべてのファイルに移動して、を追加する必要がありますする必要はないということです:ようにトップレベルのフォルダ内のメタクラスを設定する方法はありPython:フォルダ内のすべてのファイルのメタクラスを設定する
__metaclass__ = myMeta
メタクラスの使用下にあるすべてのファイル?
いいえ、クラス単位またはモジュール単位でのみメタクラスを指定できます。パッケージ全体に設定することはできません。 builtins.__build_class__
フックインターセプト
のPython 3.1では以降、あなたはできとOverriding the default type() metaclass before Python runsを参照して、プログラム的メタクラスを挿入します。
Python 2.7では、__builtins__.object
をメタクラスを使用するサブクラスに置き換えることができます。 builtins.__build_class__
フックのように、これは高度なハッカーであり、永遠にメタクラスを取得するのと同じくらいコードを壊します。
__builtin__
moduleにobject
参照を置き換えることによってそう:
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()
効果を制限します。
すごい!私はそれを試してみるつもりです。ありがとうございました! – slashdottir
ここには簡単なテクニックがあります。ちょうどサブクラスクラスそれ自体はサブクラスに__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に更新しました。それはもう一つのハックです。 –