首页 > 解决方案 > python 2和python 3的'functools.lru_cache'有什么变化吗?

问题描述

我的代码在这里可以正常工作,但从python 2 到 python 3python2.7的任何更改都失败了。python 3 functools.lru_cache(maxsize=32)

我得到的错误是我的configparser对象在缓存中functools.lru_cache

TypeError: unhashable type: 'ConfigParser'

想了解'functools.lru_cache'python 2 和 python 3 的变化吗?

#CONFI FILE
[translate]
api_url = https://url
api_version = version_num
api_key = key_value


#code goes here
import functools
from configparser import ConfigParser as SafeConfigParser
config = SafeConfigParser()
path ="./conf/services.ini"
config.read(path)


@functools.lru_cache(maxsize=32)
def build_api_params_key(config):
    """Build the api url and return with key."""
    api_url = config.get('translate', 'api_url')
    api_version = config.get('translate', 'api_version')
    api_key = config.get('translate', 'api_key')
    full_api_url = api_url + api_version

    return api_key

标签: pythonpython-3.xpython-2.7functools

解决方案


这里的问题不是functools.lru_cache,它实际上是 ConfigParser。ConfigParser继承自RawConfigParser,在 Python 3x 中,继承自collections.abc.MutableMapping. 抽象类是不可散列的MutableMapping,因为它是可变的并且不实现__hash__魔术方法。

由于ConfigParser实例不可散列,它不能用作functools.lru_cache装饰器中缓存字典的键。

如需进一步参考,请参阅configparser 文档的这一部分

假设需要缓存配置文件的内容,另一种选择是读取文件的内容,然后将内容字符串传递给缓存的函数,就像这样

import functools
from configparser import ConfigParser as SafeConfigParser
path = "./conf/services.ini"
config_contents = open(path).read()

@functools.lru_cache(maxsize=32)
def build_api_params_key(config_contents: str):
    """Build the api url and return with key."""
    config = SafeConfigParser()
    config.read_string(config_contents)
    api_url = config.get('translate', 'api_url')
    api_version = config.get('translate', 'api_version')
    api_key = config.get('translate', 'api_key')
    full_api_url = api_url + api_version

    return api_key

在上面的解决方案中,读取配置文件以获取包含其内容的字符串。由于字符串是可散列的,因此可以将其传递给缓存函数。如果您希望在函数中读取文件的内容,也可以对文件指针执行类似的操作。但是,这些解决方案与read_string未定义的 Python 2.7 不兼容。


推荐阅读