[Python] Python - anyone have a memoizing decorator that can handle unhashable arguments?

Discussão em 'Python' iniciado por Stack, Agosto 2, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using the following memoizing decorator (from the book Python Algorithms: Mastering Basic Algorithms in the Python Language).

    def memo(func):
    cache = {}
    @ wraps(func)
    def wrap(*args):
    if args not in cache:
    cache[args] = func(*args)
    return cache[args]
    return wrap


    The problem with this decorator is that the dictionary-based cache means that all arguments must be hashable.

    Does anyone have an implementation that allows for unhashable arguments (e.g. dictionaries)?

    The lack of a hash value means that the question of "is this in the cache?" becomes non-trivial.

    ===EDITED TO GIVE CONTEXT===

    I am working on a function that returns a Parnas-style "uses hierarchy" given a dictionary of module: dependencies. Here's the setup:

    def uses_hierarchy(requirements):
    """
    uses_hierarchy(requirements)

    Arguments:
    requirements - a dictionary of the form {mod: list of dependencies, }

    Return value:
    A dictionary of the form {level: list of mods, ...}

    Assumptions:
    - No cyclical requirements (e.g. if a requires b, b cannot require a).
    - Any dependency not listed as a mod assumed to be level 0.

    """

    levels = dict([(mod, _level(mod, requirements))
    for mod in requirements.iterkeys()])
    reversed = dict([(value, []) for value in levels.itervalues()])
    for k, v in levels.iteritems():
    reversed[v].append(k)
    return reversed


    def _level(mod, requirements):
    if not requirements.has_key(mod):
    return 0
    dependencies = requirements[mod]
    if not dependencies:
    return 0
    else:
    return max([_level(dependency, requirements)
    for dependency in dependencies]) + 1


    So that:

    >>> requirements = {'a': [],
    ... 'b': [],
    ... 'c': ['a'],
    ... 'd': ['a','b'],
    ... 'e': ['c','d'],
    ... 'f': ['e']
    ... }

    >>> uses_hierarchy(requirements)
    {0: ['a', 'b'], 1: ['c', 'd'], 2: ['e'], 3: ['f']}


    _level is the function I want to memoize to make this setup more scalable. As implemented without memoization, it calculates the level of dependencies multiple times (e.g. 'a' is calculated 8 times I think in the example above).

    Continue reading...

Compartilhe esta Página