2017-07-24 38 views
-1

我做了一個小型的加密器類,它需要一個字(一個string)作爲輸入,並返回liststring s。加密速度慢,所以我緩存結果,以防我想再次加密相同的單詞。 (在下面的代碼中,實際加密已被替換爲一些虛擬代碼) 以下代碼不起作用,因爲encrypt會將非常量引用返回給內部。 什麼將是一個很好的pythonian方式來解決這個問題? 我需要能夠與=+=一起使用它,如圖所示。Python成員函數返回非const引用內部 - 需要pythonian修復

class Encryptor(): 
    def __init__(self): 
     self.cache = {} 

    def encrypt(self, word): 
     if word in self.cache: 
      return self.cache[word] 
     encrypted = list("<" + word + ">") 
     self.cache[word] = encrypted 
     return encrypted 


encryptor = Encryptor() 

encrypted_text = encryptor.encrypt("this") 
encrypted_text += encryptor.encrypt("is") 
encrypted_text += encryptor.encrypt("good") 
encrypted_text += encryptor.encrypt("this") 
encrypted_text += encryptor.encrypt("is") 
encrypted_text += encryptor.encrypt("not") 

print("".join(encrypted_text)) 

預期輸出:

<this><is><good><this><is><not> 

實際輸出:通過在列表returne調用+=

self.extend(other) 
return self 

這樣:

<this><is><good><this><is><good><is><not> 
+2

做一個元組,而不是列表,你在哪裏加密=元組(「<」+ word +「>」) – user1767754

+1

詳細說明@ user1767754和@jotasi--因爲你在'list'上使用'+ =',列表是可變的,重新改變這個'list'。 「list」對象存儲在'encryptor.cache [「this」]'中,因此也會改變。要麼返回一個副本,要麼使用'tuple's。 – Kendas

+3

爲什麼你甚至使用中間名單?只需使用'str'。或者在班級外部保留一個列表累加器。 –

回答

1

你在找什麼是「備忘錄」。以pythonic的方式,這是通過裝飾者的解決。你基本上可以定義一個裝飾器來查找字典中的一個項目並返回它,如果沒有任何東西,它會生成新的數據。

這裏是你的情況的一個例子:(順便說一句,我不會使用列表您的問題,但字符串或其他類型的可哈希)

class Memoize: 
    def __init__(self, fn): 
     self.fn = fn 
     self.memo = {} 

    def __call__(self, *args): 
     if args not in self.memo: 
     self.memo[args] = self.fn(*args) 
     return self.memo[args] 


@Memoize 
def encrypt(word): 
    return tuple("<" + word + ">") 

encrypted_text = encrypt("1") 
encrypted_text += encrypt("2") 
encrypted_text += encrypt("3") 
encrypted_text += encrypt("1") 

print("".join(encrypted_text)) 

更多信息: http://www.python-course.eu/python3_memoization.php

0

list.__iadd__(other)被實現爲你要改變緩存的值。

的解決方案是樸素簡單:不要存儲列表,存儲的字符串,並使其成爲一個列表(如果你真的需要一個列表)剛剛返回前...

def encrypt(self, word): 
    if word not in self.cache:   
     self.cache[word] = "<" + word + ">" 
    return list(self.cache[word]) 

或更好的讓客戶取使之成爲一個列表(或其他)的責任:

def encrypt(self, word): 
    if word not in self.cache:   
     self.cache[word] = "<" + word + ">" 
    return self.cache[word] 

然後

encryptor = Encryptor() 

encrypted_text = list(encryptor.encrypt("this")) 
encrypted_text += list(encryptor.encrypt("is")) 
encrypted_text += list(encryptor.encrypt("good")) 

相關問題