'functools.lru_cache' 与 python 2 和 python 3 相比有何变化?
Any changes in 'functools.lru_cache' from python 2 and python 3?
我的代码在 python2.7
中工作正常,但在 python 3
中失败
functools.lru_cache(maxsize=32)
从 python 2 到 python 3 的任何变化。
我得到的错误是我的 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
这里的问题不是functools.lru_cache
,而是ConfigParser。 ConfigParser
继承自 RawConfigParser
,后者在 Python 3x 中继承自 collections.abc.MutableMapping
。 MutableMapping
抽象 class 不可散列,因为它是可变的并且没有实现 __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
在上面的解决方案中,读取配置文件以获取包含其内容的字符串。由于字符串是可哈希的,因此可以将其传递给缓存函数。如果您更愿意在函数内读取文件的内容,您也可以对文件指针执行类似的操作。但是,这些解决方案与 Python 2.7 不兼容,因为 read_string
未定义。
我的代码在 python2.7
中工作正常,但在 python 3
中失败
functools.lru_cache(maxsize=32)
从 python 2 到 python 3 的任何变化。
我得到的错误是我的 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
这里的问题不是functools.lru_cache
,而是ConfigParser。 ConfigParser
继承自 RawConfigParser
,后者在 Python 3x 中继承自 collections.abc.MutableMapping
。 MutableMapping
抽象 class 不可散列,因为它是可变的并且没有实现 __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
在上面的解决方案中,读取配置文件以获取包含其内容的字符串。由于字符串是可哈希的,因此可以将其传递给缓存函数。如果您更愿意在函数内读取文件的内容,您也可以对文件指针执行类似的操作。但是,这些解决方案与 Python 2.7 不兼容,因为 read_string
未定义。