2017-07-24 36 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")) 

相关问题