我制作了一个小型的Encryptor类,它接受一个单词(string
)作为输入,并返回list
个string
个。加密速度很慢,所以我会缓存结果,以防我想再次加密同一个字。 (在下面的代码中,实际加密已被一些虚拟代码替换)
以下代码不起作用,因为encrypt
返回对内部的非const引用。
什么是一个很好的蟒蛇方式来解决这个问题?
如图所示,我需要能够同时使用=
和+=
。
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>
实际输出:
<this><is><good><this><is><good><is><not>
答案 0 :(得分:1)
您正在寻找的是&#34; memoization &#34;。以pythonic方式,这是通过装饰者解决的。你基本上可以定义一个Decorator来查找字典中的一个项目并返回它,如果没有,它会生成新的数据。
以下是您的案例示例:(顺便说一句,我不会为您的问题使用列表,但字符串或其他可清除类型)
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))
答案 1 :(得分:0)
list.__iadd__(other)
实现为:
self.extend(other)
return self
所以通过在返回的列表上调用+=
,你可以改变缓存的值。
解决方案很简单:在返回之前,不要存储列表,存储字符串并使其成为列表(如果确实需要列表)...
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"))
等