2015-05-17 2 views
2

Я использую запоминание декоратор:демпинг запоминание кэш декоратора в файл

class memoize: 

    def __init__(self, fn): 
     self.fn = fn 
     self.memo = {} 
     if os.path.isfile(filename): 
      self.memo = pickle.load(open(filename, "rb")) 
     else: 
      self.memo = {} 
    def __call__(self, *args, **kwds): 
     str = pickle.dumps(args, 1) + pickle.dumps(kwds, 1) 
     if not self.memo.has_key(str): 
      self.memo[str] = self.fn(*args, **kwds) 
     return self.memo[str] 

А потом я использую @memoize на функцию, которые я хочу, чтобы применить его к.

Однако я попытаюсь, после того как я закончил, сохранить кеш в памяти.

pickle.dump(memoize.memo, open(filename, "wb")) 

Не работает. Как мне исправить? «AttributeError: класс memoize не имеет атрибута„памятка“»

+1

В качестве примечания, вы можете рассмотреть вопрос об использовании [ 'shelve'] (https://docs.python.org/3/library/shelve.html) вместо «dict» в качестве кеша, поэтому он всегда хранится в синхронизации на диске, причем еще меньше кода, чем у вас здесь (и без проблема, которую вы пытаетесь решить здесь). – abarnert

ответ

2

Вы должны были бы создать экземпляр, это экземпляр атрибут не атрибут класса:

pickle.dump(memoize(func).memo... 

Если вы хотите получить доступ к памятке от FUNC что декоратор был использован на:

@memoize 
def fib(n): 
    if n == 0: 
     return 0 
    elif n == 1: 
     return 1 
    else: 
     return fib(n-1) + fib(n-2) 


fib(30) 
print(fib.memo) 

{'(K\x0btq\x00.}q\x00.': 89, '(K\x06tq\x00.}q\x00.': 8, '(K\ntq\x00.}q\x00.': 55, '(K\x18tq\x00.}q\x00.': 46368, '(K\x1ctq\x00.}q\x00.': 317811, '(K\x15tq\x00.}q\x00.': 10946, '(K\x10tq\x00.}q\x00.': 987, '(K\x19tq\x00.}q\x00.': 75025, '(K\x13tq\x00.}q\x00.': 4181, '(K\x11tq\x00.}q\x00.': 1597, '(K\x12tq\x00.}q\x00.': 2584, '(K\x00tq\x00.}q\x00.': 0, '(K\ttq\x00.}q\x00.': 34, '(K\x04tq\x00.}q\x00.': 3, '(K\x1etq\x00.}q\x00.': 832040, '(K\x16tq\x00.}q\x00.': 17711, '(K\x0ftq\x00.}q\x00.': 610, '(K\x0etq\x00.}q\x00.': 377, '(K\x07tq\x00.}q\x00.': 13, '(K\x14tq\x00.}q\x00.': 6765, '(K\x08tq\x00.}q\x00.': 21, '(K\x0ctq\x00.}q\x00.': 144, '(K\x05tq\x00.}q\x00.': 5, '(K\x1dtq\x00.}q\x00.': 514229, '(K\x03tq\x00.}q\x00.': 2, '(K\x01tq\x00.}q\x00.': 1, '(K\x17tq\x00.}q\x00.': 28657, '(K\x02tq\x00.}q\x00.': 1, '(K\x1btq\x00.}q\x00.': 196418, '(K\x1atq\x00.}q\x00.': 121393, '(K\rtq\x00.}q\x00.': 2} 

Для того, чтобы понять, каждый раз, когда вы украшаете функцию новой памятки ДИКТ создан таким образом, вы не может доступ к глобальной версии записки, потому что его нет.

Если вы хотите получить доступ к нему из класса и разделить его между всеми функциями вы сделали бы это атрибут класса:

class memoize: 
    memo = {} 
    def __init__(self, fn): 
     self.fn = fn 
     if os.path.isfile(""): 
      memoize.memo = pickle.load(open(filename, "rb")) 
     else: 
      memoize.memo = {} 
    def __call__(self, *args, **kwds): 
     str = pickle.dumps(args, 1) + pickle.dumps(kwds, 1) 
     if not self.memo.has_key(str): 
      memoize.memo[str] = self.fn(*args, **kwds) 
     return memoize.memo[str] 


fib(100) 


fib(1) 
print(memoize.memo) 
{'(K,tq\x00.}q\x00.': 701408733, '(K\x0btq\x00.}q\x00.': 89, '(K?tq\x00.}q\x00.': 6557470319842, '(K=tq\x00.}q\x00.': 2504730781961, '(K"tq\x00.}q\x00.': 5702887, '(K\x10tq\x00.}q\x00.': 987, '(K;tq\x00.}q\x00.': 956722026041, '(K\x11tq\x00.}q\x00.': 1597, '(K\x00tq\x00.}q\x00.': 0, '(K\x1etq\x00.}q\x00.': 832040, '(KBtq\x00.}q\x00.': 27777890035288, '(K0tq\x00.}q\x00.': 4807526976, '(K\x0ftq\x00.}q\x00.': 610, '(K\x0etq\x00.}q\x00.': 377, '(Kctq\x00.}q\x00.': 218922995834555169026L, '(K6tq\x00.}q\x00.': 86267571272, '(KYtq\x00.}q\x00.': 1779979416004714189, '(K.tq\x00.}q\x00.': 1836311903, '(K\x02tq\x00.}q\x00.': 1, '(KGtq\x00.}q\x00.': 308061521170129, '(K%tq\x00.}q\x00.': 24157817, '(Kdtq\x00.}q\x00.': 354224848179261915075L, '(K\x19tq\x00.}q\x00.': 75025, '(K:tq\x00.}q\x00.': 591286729879, '(K\x13tq\x00.}q\x00.': 4181, '(K&tq\x00.}q\x00.': 39088169, '(K\ttq\x00.}q\x00.': 34, '(K*tq\x00.}q\x00.': 267914296, '(K]tq\x00.}q\x00.': 12200160415121876738L, '(KCtq\x00.}q\x00.': 44945570212853, '(KWtq\x00.}q\x00.': 679891637638612258, '(K5tq\x00.}q\x00.': 53316291173, '(K\x16tq\x00.}q\x00.': 17711, '(K9tq\x00.}q\x00.': 365435296162, '(KMtq\x00.}q\x00.': 5527939700884757, '(K3tq\x00.}q\x00.': 20365011074, '(K\x07tq\x00.}q\x00.': 13, '(K$tq\x00.}q\x00.': 14930352, '(K\\tq\x00.}q\x00.': 7540113804746346429, '(KQtq\x00.}q\x00.': 37889062373143906, "(K'tq\x00.}q\x00.": 63245986, '(KRtq\x00.}q\x00.': 61305790721611591, '(KDtq\x00.}q\x00.': 72723460248141, '(K\x1dtq\x00.}q\x00.': 514229, '(KNtq\x00.}q\x00.': 8944394323791464, '(K`tq\x00.}q\x00.': 51680708854858323072L, '(K!tq\x00.}q\x00.': 3524578, '(K\x1ctq\x00.}q\x00.': 317811, '(K-tq\x00.}q\x00.': 1134903170, '(KLtq\x00.}q\x00.': 3416454622906707, '(K\x12tq\x00.}q\x00.': 2584, '(K\x04tq\x00.}q\x00.': 3, '(K_tq\x00.}q\x00.': 31940434634990099905L, '(K8tq\x00.}q\x00.': 225851433717, '(K<tq\x00.}q\x00.': 1548008755920, '(K[tq\x00.}q\x00.': 4660046610375530309, '(KZtq\x00.}q\x00.': 2880067194370816120, '(K2tq\x00.}q\x00.': 12586269025, '(K tq\x00.}q\x00.': 2178309, '(KFtq\x00.}q\x00.': 190392490709135, '(KJtq\x00.}q\x00.': 1304969544928657, '(KXtq\x00.}q\x00.': 1100087778366101931, '(K>tq\x00.}q\x00.': 4052739537881, '(KUtq\x00.}q\x00.': 259695496911122585, '(K/tq\x00.}q\x00.': 2971215073, '(KStq\x00.}q\x00.': 99194853094755497, '(K\x0ctq\x00.}q\x00.': 144, '(KItq\x00.}q\x00.': 806515533049393, '(K\x1ftq\x00.}q\x00.': 1346269, '(K\x1btq\x00.}q\x00.': 196418, '(KVtq\x00.}q\x00.': 420196140727489673, '(K\x1atq\x00.}q\x00.': 121393, '(K\x06tq\x00.}q\x00.': 8, '(K\ntq\x00.}q\x00.': 55, '(K\x18tq\x00.}q\x00.': 46368, '(K#tq\x00.}q\x00.': 9227465, '(K7tq\x00.}q\x00.': 139583862445, '(K\x15tq\x00.}q\x00.': 10946, '(KTtq\x00.}q\x00.': 160500643816367088, '(KHtq\x00.}q\x00.': 498454011879264, '(KEtq\x00.}q\x00.': 117669030460994, '(K+tq\x00.}q\x00.': 433494437, '(KAtq\x00.}q\x00.': 17167680177565, '(K1tq\x00.}q\x00.': 7778742049, '(KKtq\x00.}q\x00.': 2111485077978050, '(K)tq\x00.}q\x00.': 165580141, '(Katq\x00.}q\x00.': 83621143489848422977L, '(Kbtq\x00.}q\x00.': 135301852344706746049L, '(KPtq\x00.}q\x00.': 23416728348467685, '(K\x14tq\x00.}q\x00.': 6765, '(K\x08tq\x00.}q\x00.': 21, '(K\x05tq\x00.}q\x00.': 5, '([email protected]\x00.}q\x00.': 10610209857723, '(K\x03tq\x00.}q\x00.': 2, '(K^tq\x00.}q\x00.': 19740274219868223167L, '(K\x01tq\x00.}q\x00.': 1, '(K\x17tq\x00.}q\x00.': 28657, '(K4tq\x00.}q\x00.': 32951280099, '(KOtq\x00.}q\x00.': 14472334024676221, '(K\rtq\x00.}q\x00.': 233, '(K(tq\x00.}q\x00.': 102334155} 
+0

@ user4906860 Конечно, foo не работает, я показывал вам, как обращаться к памятке –

+0

@ user4906860, я точно знаю, что это такое, я просто объяснял разницу между атрибутами экземпляра –

+0

@ user4906860, нет глобального экземпляра, каждый раз, когда он используется, создается экземпляр, имеющий тот же кеш для нескольких функций, был бы довольно неэффективным –