Python のすべてのクラスを変更したいと思います。たとえば、str や int など、Person(object) などがあります。
それらに属性を追加し、そのメソッドの動作方法を変更したいと思います。
これに最適なアプローチはどれですか? メタクラス?
属性を再割り当てすることにより、Python コードで定義されたクラスに対してこれを行うことができますが (組み込みのクラスでは機能しません)、実際にはそうしないでください。サブクラス化してサブクラスを使用するか、独自のメソッドを追加する代わりに、クラスのインスタンスを引数として取る関数を記述します。特に、同じクラスに対してこれを実行しようとする複数のライブラリを同時に使用することになった場合は特にそうです。
この方法で解決しようとしている実際の問題はありますか?
組み込みクラスは変更できませんが、同じ名前のいずれかで組み込みクラス (またはもちろん他のクラス) を「隠す」ことができます。
たとえば、一連のクラスに初期値が 23 の新しい属性「foobar」を追加し、これらのクラスのすべてのインスタンスに初期値が 45 の新しい属性「murf」を追加するとします。方法の 1 つを次に示します。
def changedclass(cls):
def __init__(self, *a, **k):
cls.__init__(self, *a, **k)
self.murf = 45
return type(cls.__name__, (cls,), {'foobar': 23, '__init__': __init__})
def changemany(changed, classes_by_module):
for module, classnames in classes_by_module.iteritems():
for name in classnames:
cls = getattr(module, name)
subcls = changed(cls)
setattr(module, name, subcls)
import __builtin__
import mymod
changemany(changedclass, {__builtin__: ('int', 'str'), mymod: ('Person',)})
'ciao' や 23 などの生のリテラルは、依然として実際のクラスに属していることに注意してください。これを変更する方法はありません。「偽の」クラスを使用して使用するstr('ciao')
必要があります。int(23)
サブクラス:
class int(int):
def foo(self):
print "foo"
int(2).foo()
javascript のプロトタイプ属性のようにクラスを直接編集することはできません。それらをサブクラス化した方がよいでしょう。これにより、必要な機能を追加でき、どこでも使用する必要がなくなります。