Какие-либо изменения в 'functools.lru_cache' от python 2 и python 3? - PullRequest
0 голосов
/ 07 ноября 2019

Мой код здесь отлично работает в 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

1 Ответ

0 голосов
/ 08 ноября 2019

Проблема здесь не 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

В приведенном выше решении файл конфигурации читается для получения строкисодержащий его содержимое. Поскольку строки можно хэшировать, это можно передать в кэшированную функцию. Вы также можете сделать нечто подобное с указателем файла, если вы предпочитаете читать содержимое файла внутри функции. Однако эти решения не совместимы с Python 2.7, так как read_string не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...