__new__
を呼び出し、タイプをメタクラスとして使用している場合は、__new__
の結果がタイプのサブタイプである場合は、__init__
が呼び出されます。別の言い方をすると、クラスFooがあるとしましょう。 PyObject_Type(self)
の結果を呼び出す場合は、Foo()
と同じです。これはFooを意味します。 __new__
が呼び出され、戻り値がFooのサブタイプの場合は、__init__
が呼び出されます。
Foo()を呼び出すと、実際にtype_call(typeobject.c内)が呼び出されます。これは、tp_newの後にtp_initが続くものです。オブジェクトの新しい機能(PyObject_Type(self)ではなくFoo_new()など)を直接提供する場合は、__init__
を呼び出さずに__new__
を呼び出して、探しているものを得ることができます。 (Fooを__new__
の引数として提供することを忘れないでください)。
最後に質問にお答えするには、Foo.__new__(Foo, ...)
に電話してください。あなたが探しているものを行うコードがいくつかあります。私はこのすべてを把握しようとしていたとき、余談として
class Foo(object):
def __new__(cls):
return super(Foo, cls).__new__(cls)
def __init__(self):
print "__init__"
def __reduce__(self):
return (Foo.__new__, (Foo,))
print "one"
x = Foo() # prints __init__
print "two"
y = Foo.__new__(Foo) # does not print __init__
print "three"
import pickle
p = pickle.dumps(Foo)
z = pickle.loads(p) # does not print __init__
は、私はほとんどすべてのケースで、私は、実際には、私のコードを実装し、__init__
が呼ばれることを可能にすることを見出しました。私のエラーは、私が__reduce__
タプルの3番目の引数に入るものを分離していないという事実に起因しています。 (__init__
がそれを受け入れるならば)2番目の議論のために何も提供するのは完全にOKであり、__dict__
を直接更新する3番目の議論のものを提供するだけです。モジュールとオブジェクトのディレクトリにあるcpythonのソースコードを見ると、__reduce__
の実装がいくつも見られます。
原則として、 '__init__'は呼び出されるべきではありません。それはpickleの好ましい方法です。 '__getinitargs__'を参照してください:" pickleされたクラスインスタンスがunpickleされているとき、その '__init __()'メソッドは通常は呼び出されません*。 '__getinitargs__'を実装していますか? –
元気です。それは普通のクラスのためだけです。 –