私は最初に使用した後にキャッシュされるオブジェクトを持っています。私はcPickleモジュールを使ってこれを行います。モジュールが既にキャッシュされている場合、次回(別のプロセスで)オブジェクトをインスタンス化しようとすると、キャッシュされたオブジェクトを使用したいと思います。以下の私の基本的な構造です:Xクラスの__new__メソッドのX型のオブジェクトのピックを解除すると、unpickleオブジェクトを返すときに__init__が呼び出されます。なぜですか?
import cPickle
class Test(object):
def __new__(cls, name):
if name == 'john':
print "using cached object"
with open("cp.p", "rb") as f:
obj = cPickle.load(f)
print "object unpickled"
return obj
else:
print "using new object"
return super(Test, cls).__new__(cls, name)
def __init__(self, name):
print "calling __init__"
self.name = name
with open("cp.p", "wb") as f:
cPickle.dump(self, f)
問題は、私は__new__
方法でキャッシュされたオブジェクトをunpickle化するとき、それは__init__
を呼び出して、すべてを再初期化していることです。興味深いことに、__init__
は、unpickleの後ではなく、unpickleされたオブジェクトが返されたときのように呼び出されます。私はこれを示すprintステートメントを追加しました( "オブジェクトunpickled")。
私は__init__
に次のチェックを追加することにより、ハックの回避策があります。
intiailzed = False
...
...
def __init__(self, name):
if not self.intialized:
self.initialized = True
# Rest of the __init__ here
と同様に初期化と呼ばれるクラスの属性を、これは明らかに理想的ではありません。
__init__
メソッドを抑制する方法についての洞察(またはなぜそれが全く呼び出されているのか)を理解できます。 Test.__new__(Test, name)
から返さunpickle化オブジェクトはTest
のインスタンスであるので、その__init__
obj = Test.__new__(Test, name)
if isinstance(obj, Test):
obj.__init__(name)
:
編集:このような
class Test(object):
def __new__(cls, name=None):
print "calling __new__"
if name == 'john':
print "using cached object"
with open("cp.p", "rb") as f:
obj = cPickle.load(f)
print "object unpickled"
return obj
else:
print "using new object"
obj = super(Test, cls).__new__(cls, name)
obj.initialize(name)
return obj
def __init__(self, name):
pass
def initialize(self, name):
print "calling __init__"
self.name = name
with open("cp.p", "wb") as f:
cPickle.dump(self, f)
["__new __()がclsのインスタンスを返す場合は、新しいインスタンスの__init __()メソッドが呼び出されます"](https://docs.python.org/2/reference/datamodel.html) #object .__ new__) – unutbu
[Python 2.2で統一されている型とクラス](https://www.python.org/download/releases/2.2.3/descrintro/#__new__)で、 "不変型にはダミー' __init__ '、mutable型はダミー' __new__'を持っています。 "正当な理由がないかぎり、あなたのクラスは同じパターンに従うべきです。 – unutbu
これは、私が実際に自分のポイントをもっと簡単に得るために単純に一般化したものです。条件は大きく異なります。しかし、ヒントをお寄せいただきありがとうございます。私の条件が満たされ、ファイルが存在しないかどうかを検討するのは、おそらく悪いことではありませんが、失敗するようにしたいと思います。 –