İlk kullanımdan sonra önbelleğe alınacak bir nesnem var. Bunu cPickle modülünü kullanarak yapacağım. Modül önbelleğe alınmışsa, nesneyi bir dahaki seferde (başka bir işlemde) başlatmaya çalıştığımda, önbelleğe alınmış nesneyi kullanmak istiyorum. Aşağıdaki benim temel yapıdır:X sınıfının __new__ yöntemindeki X türünde unpickling nesnesi, ayrılmamış nesneyi döndürme konusunda __init__ çağrısında bulunur, neden?
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)
Sorun __new__
yönteminde önbelleğe nesne unpickle zaman __init__
çağırır ve her şeyi reinitializes olmasıdır. İlginç bir şekilde, __init__
unpickling'den sonra değil, unpickled nesnesi döndüğünde çağrılır. Bunu gösteren bir "print ifadesi" ekledim ("object unpickled").
__init__
aşağıdaki onay ekleyerek hacky geçici çözüm vardır:
intiailzed = False
...
...
def __init__(self, name):
if not self.intialized:
self.initialized = True
# Rest of the __init__ here
yanı sıra başlatıldı denilen class özelliği, ancak bu besbelli ideal değildir.
__init__
yöntemini (ya da neden çağrıldığını) nasıl bastırılacağına ilişkin herhangi bir fikir takdir edilecektir.
Düzenleme: Böyle
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)
Dokümanlar, ["__new __(), cls örneğini döndürürse, yeni örneğin __init __() yöntemi çağrılır"] (https://docs.python.org/2/reference/datamodel.html #object .__ new__) – unutbu
Başına [Python 2.2'deki türleri ve sınıfları birleştirmek] (https://www.python.org/download/releases/2.2.3/descrintro/#__new__), "değişmez türlerin bir kukla var" __init__ ', değişken tiplerde bir' __new__' kukla var. ' İyi bir nedeniniz olmadıkça (ve hiçbirini bilmiyorum), sınıflarınız da aynı düzeni izlemelidir. – unutbu
Bu, aslında daha kolay noktayı elde etmek için sahip olduğum şeyin basitleştirilmiş bir genellemesiydi, koşullar çok farklı. Ancak bahşiş için teşekkürler, muhtemelen kötü bir şey olmamasına rağmen benim durumumun yerine getirilip getirilmediğini ve dosyanın mevcut olmadığını düşünmeme izin vermem. –