我的代码在python2.7
中运行良好,但在python 3
functools.lru_cache(maxsize=32)
中,从Python2到Python3的任何更改都失败。
我得到的错误是在functools.lru_cache
中缓存时我的configparser
对象,它说
TypeError: unhashable type: 'ConfigParser'
想了解Python2和Python3在'functools.lru_cache'
中的变化吗?
#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
发布于 2019-11-08 01:39:39
这里的问题不是functools.lru_cache
,而是ConfigParser。ConfigParser
继承自RawConfigParser
,在Python3x中继承自collections.abc.MutableMapping
。MutableMapping
抽象类是不可哈希的,因为它是可变的,并且没有实现__hash__
魔术方法。
由于ConfigParser
实例不可哈希,因此不能将其用作functools.lru_cache
装饰器中缓存字典的键。
有关进一步的参考,请参阅this section of the configparser docs。
假设有必要缓存配置文件的内容,另一种选择是读取文件的内容,然后将内容字符串传递给缓存的函数,如下所示
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
在上面的解决方案中,读取配置文件以获取包含其内容的字符串。因为字符串是可散列的,所以可以将其传递给缓存函数。如果您更愿意在函数中读取文件的内容,也可以使用文件指针执行类似的操作。然而,这些解决方案与Python2.7不兼容,因为没有定义read_string
。
https://stackoverflow.com/questions/58749254
复制相似问题