Python成员函数返回对内部的非const引用 - 需要pythonian修复

时间:2017-07-24 09:05:17

标签: python reference return

我制作了一个小型的Encryptor类,它接受一个单词(string)作为输入,并返回liststring个。加密速度很慢,所以我会缓存结果,以防我想再次加密同一个字。 (在下面的代码中,实际加密已被一些虚拟代码替换) 以下代码不起作用,因为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>

2 个答案:

答案 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))

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

答案 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"))